market types from mammon
This commit is contained in:
@@ -449,6 +449,37 @@ paths:
|
||||
$ref: "#/components/schemas/MarketHistoryResponse"
|
||||
"400":
|
||||
description: The days parameter is not greater than 0
|
||||
/market/types:
|
||||
get:
|
||||
tags:
|
||||
- market
|
||||
summary: Return the static market type details for each requested type id
|
||||
operationId: findTypes
|
||||
parameters:
|
||||
- name: ids
|
||||
in: query
|
||||
description: "Market type ids to look up, e.g. ids=34,35"
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"200":
|
||||
description: The market types found for the requested ids; unknown ids are
|
||||
omitted
|
||||
content:
|
||||
'*/*':
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/MarketTypeResponse"
|
||||
"400":
|
||||
description: |-
|
||||
Returned when:
|
||||
- the ids parameter is missing
|
||||
- an ids value is not a numeric id
|
||||
/market/scan:
|
||||
get:
|
||||
tags:
|
||||
@@ -916,6 +947,46 @@ components:
|
||||
- marketTypeId
|
||||
- orderCount
|
||||
- volume
|
||||
MarketTypeResponse:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
groupId:
|
||||
type: integer
|
||||
format: int64
|
||||
marketGroupId:
|
||||
type: integer
|
||||
format: int64
|
||||
description:
|
||||
type: string
|
||||
published:
|
||||
type: boolean
|
||||
basePrice:
|
||||
type: number
|
||||
volume:
|
||||
type: number
|
||||
format: double
|
||||
portionSize:
|
||||
type: integer
|
||||
format: int32
|
||||
iconId:
|
||||
type: integer
|
||||
format: int64
|
||||
required:
|
||||
- basePrice
|
||||
- description
|
||||
- groupId
|
||||
- iconId
|
||||
- id
|
||||
- marketGroupId
|
||||
- name
|
||||
- portionSize
|
||||
- published
|
||||
- volume
|
||||
MarketPriceResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -124,6 +124,18 @@ export interface MarketScanResponse {
|
||||
'profit': number;
|
||||
'score': number;
|
||||
}
|
||||
export interface MarketTypeResponse {
|
||||
'id': number;
|
||||
'name': string;
|
||||
'groupId': number;
|
||||
'marketGroupId': number;
|
||||
'description': string;
|
||||
'published': boolean;
|
||||
'basePrice': number;
|
||||
'volume': number;
|
||||
'portionSize': number;
|
||||
'iconId': number;
|
||||
}
|
||||
export interface RuleBookResponse {
|
||||
'ruleBookId': string;
|
||||
'name': string;
|
||||
@@ -1352,6 +1364,43 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Return the static market type details for each requested type id
|
||||
* @param {Array<number>} ids Market type ids to look up, e.g. ids=34,35
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findTypes: async (ids: Array<number>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'ids' is not null or undefined
|
||||
assertParamExists('findTypes', 'ids', ids)
|
||||
const localVarPath = `/market/types`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
if (ids) {
|
||||
localVarQueryParameter['ids'] = ids;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Accept'] = '*/*';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Scan every tracked market type, returning volume-weighted price quartiles for each
|
||||
@@ -1482,6 +1531,19 @@ export const MarketApiFp = function(configuration?: Configuration) {
|
||||
const localVarOperationServerBasePath = operationServerMap['MarketApi.findHistory']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Return the static market type details for each requested type id
|
||||
* @param {Array<number>} ids Market type ids to look up, e.g. ids=34,35
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async findTypes(ids: Array<number>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<MarketTypeResponse>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.findTypes(ids, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['MarketApi.findTypes']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Scan every tracked market type, returning volume-weighted price quartiles for each
|
||||
@@ -1543,6 +1605,16 @@ export const MarketApiFactory = function (configuration?: Configuration, basePat
|
||||
findHistory(marketTypeId: number, days?: number, options?: RawAxiosRequestConfig): AxiosPromise<Array<MarketHistoryResponse>> {
|
||||
return localVarFp.findHistory(marketTypeId, days, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Return the static market type details for each requested type id
|
||||
* @param {Array<number>} ids Market type ids to look up, e.g. ids=34,35
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findTypes(ids: Array<number>, options?: RawAxiosRequestConfig): AxiosPromise<Array<MarketTypeResponse>> {
|
||||
return localVarFp.findTypes(ids, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Scan every tracked market type, returning volume-weighted price quartiles for each
|
||||
@@ -1598,6 +1670,17 @@ export class MarketApi extends BaseAPI {
|
||||
return MarketApiFp(this.configuration).findHistory(marketTypeId, days, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Return the static market type details for each requested type id
|
||||
* @param {Array<number>} ids Market type ids to look up, e.g. ids=34,35
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public findTypes(ids: Array<number>, options?: RawAxiosRequestConfig) {
|
||||
return MarketApiFp(this.configuration).findTypes(ids, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Scan every tracked market type, returning volume-weighted price quartiles for each
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { RegionalMarketCache } from '../RegionalMarketCache';
|
||||
import { jitaId } from '../market';
|
||||
import { MarketType } from "../type";
|
||||
import { MarketTypePrice } from './MarketTypePrice';
|
||||
import { getMammonPrices } from './mammon';
|
||||
import {defineStore} from 'pinia';
|
||||
import {RegionalMarketCache} from '../RegionalMarketCache';
|
||||
import {jitaId} from '../market';
|
||||
import {MarketType} from "../type";
|
||||
import {MarketTypePrice} from './MarketTypePrice';
|
||||
import {getMammonPrices} from './mammon';
|
||||
|
||||
const cacheDuration = 1000 * 60 * 5; // 5 minutes
|
||||
const batchSize = 100;
|
||||
const CACHE_DURATION = 1000 * 60 * 5; // 5 minutes
|
||||
const BATCH_SIZE = 100;
|
||||
|
||||
export const useApraisalStore = defineStore('appraisal', () => {
|
||||
const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(cacheDuration);
|
||||
const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(CACHE_DURATION);
|
||||
|
||||
const getPricesUncached = getMammonPrices;
|
||||
|
||||
@@ -32,8 +32,8 @@ export const useApraisalStore = defineStore('appraisal', () => {
|
||||
if (uncached.length > 0) {
|
||||
const batches: Promise<MarketTypePrice[]>[] = [];
|
||||
|
||||
for (let i = 0; i < uncached.length; i += batchSize) {
|
||||
batches.push(getPricesUncached(uncached.slice(i, i + batchSize)));
|
||||
for (let i = 0; i < uncached.length; i += BATCH_SIZE) {
|
||||
batches.push(getPricesUncached(uncached.slice(i, i + BATCH_SIZE)));
|
||||
}
|
||||
|
||||
const prices = (await Promise.all(batches)).flat();
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
import {esiAxiosInstance} from '@/service';
|
||||
import {marketApi} from '@/mammon/mammonService';
|
||||
import type {MarketTypeResponse} from '@/generated/mammon';
|
||||
|
||||
export type MarketType = {
|
||||
id: number;
|
||||
group_id: number;
|
||||
market_group_id: number;
|
||||
name: string;
|
||||
published: boolean;
|
||||
description: string;
|
||||
base_price: number;
|
||||
icon_id: number;
|
||||
volume: number;
|
||||
portion_size: number;
|
||||
}
|
||||
export type MarketType = MarketTypeResponse;
|
||||
|
||||
const cache = new Map<number, MarketType>(); // TODO move to pinia store
|
||||
|
||||
const fetchType = (id: number): Promise<MarketType> => {
|
||||
if (cache.has(id)) {
|
||||
return Promise.resolve(cache.get(id)!);
|
||||
const BATCH_SIZE = 100;
|
||||
|
||||
const fetchTypes = async (ids: number[]): Promise<void> => {
|
||||
const missing = ids.filter(id => !cache.has(id));
|
||||
if (missing.length === 0) {
|
||||
return;
|
||||
}
|
||||
return esiAxiosInstance.get<Omit<MarketType, 'id'> & { type_id: number }>(`/universe/types/${id}/`).then(r => {
|
||||
const { type_id, ...rest } = r.data;
|
||||
const marketType: MarketType = { id: type_id, ...rest };
|
||||
cache.set(id, marketType);
|
||||
return marketType;
|
||||
});
|
||||
const batches: Promise<MarketType[]>[] = [];
|
||||
for (let i = 0; i < missing.length; i += BATCH_SIZE) {
|
||||
batches.push(marketApi.findTypes(missing.slice(i, i + BATCH_SIZE)).then(r => r.data));
|
||||
}
|
||||
const results = await Promise.all(batches);
|
||||
results.flat().forEach(t => cache.set(t.id, t));
|
||||
};
|
||||
|
||||
export const getMarketType = async (type: string | number): Promise<MarketType> => (await getMarketTypes([type]))[0];
|
||||
@@ -33,28 +26,10 @@ export const getMarketTypes = async (types: (string | number)[]): Promise<Market
|
||||
return [];
|
||||
}
|
||||
const ids = types.filter((t): t is number => typeof t === 'number');
|
||||
return Promise.all(ids.map(fetchType));
|
||||
await fetchTypes(ids);
|
||||
return ids.map(id => cache.get(id)).filter((t): t is MarketType => t !== undefined);
|
||||
}
|
||||
|
||||
const blueprintMarketGroups = [ // TODO add all groups
|
||||
2,
|
||||
2157,
|
||||
2159,
|
||||
2339,
|
||||
2160,
|
||||
211,
|
||||
1016,
|
||||
339,
|
||||
2290,
|
||||
357,
|
||||
1530,
|
||||
359,
|
||||
1531,
|
||||
1532,
|
||||
1533,
|
||||
358
|
||||
]
|
||||
|
||||
export const searchMarketTypes = async (search: string): Promise<MarketType[]> => {
|
||||
export const searchMarketTypes = async (_search: string): Promise<MarketType[]> => {
|
||||
return []
|
||||
}
|
||||
@@ -89,7 +89,7 @@ watchEffect(async () => {
|
||||
<template>
|
||||
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
|
||||
<div class="fake-input">
|
||||
<img v-if="modelValue?.type_id" :src="`https://images.evetech.net/types/${modelValue.type_id}/icon?size=32`" alt="" />
|
||||
<img v-if="modelValue?.id" :src="`https://images.evetech.net/types/${modelValue.id}/icon?size=32`" alt="" />
|
||||
<input type="text" v-model="name" @keyup.enter="submit" @keyup.down="moveDown" @keyup.up="moveUp" />
|
||||
</div>
|
||||
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">
|
||||
|
||||
Reference in New Issue
Block a user