market types from mammon
This commit is contained in:
@@ -449,6 +449,37 @@ paths:
|
|||||||
$ref: "#/components/schemas/MarketHistoryResponse"
|
$ref: "#/components/schemas/MarketHistoryResponse"
|
||||||
"400":
|
"400":
|
||||||
description: The days parameter is not greater than 0
|
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:
|
/market/scan:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -916,6 +947,46 @@ components:
|
|||||||
- marketTypeId
|
- marketTypeId
|
||||||
- orderCount
|
- orderCount
|
||||||
- volume
|
- 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:
|
MarketPriceResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -124,6 +124,18 @@ export interface MarketScanResponse {
|
|||||||
'profit': number;
|
'profit': number;
|
||||||
'score': 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 {
|
export interface RuleBookResponse {
|
||||||
'ruleBookId': string;
|
'ruleBookId': string;
|
||||||
'name': string;
|
'name': string;
|
||||||
@@ -1352,6 +1364,43 @@ export const MarketApiAxiosParamCreator = function (configuration?: Configuratio
|
|||||||
options: localVarRequestOptions,
|
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
|
* @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;
|
const localVarOperationServerBasePath = operationServerMap['MarketApi.findHistory']?.[localVarOperationServerIndex]?.url;
|
||||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
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
|
* @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>> {
|
findHistory(marketTypeId: number, days?: number, options?: RawAxiosRequestConfig): AxiosPromise<Array<MarketHistoryResponse>> {
|
||||||
return localVarFp.findHistory(marketTypeId, days, options).then((request) => request(axios, basePath));
|
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
|
* @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));
|
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
|
* @summary Scan every tracked market type, returning volume-weighted price quartiles for each
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { MarketType } from "../type";
|
|||||||
import {MarketTypePrice} from './MarketTypePrice';
|
import {MarketTypePrice} from './MarketTypePrice';
|
||||||
import {getMammonPrices} from './mammon';
|
import {getMammonPrices} from './mammon';
|
||||||
|
|
||||||
const cacheDuration = 1000 * 60 * 5; // 5 minutes
|
const CACHE_DURATION = 1000 * 60 * 5; // 5 minutes
|
||||||
const batchSize = 100;
|
const BATCH_SIZE = 100;
|
||||||
|
|
||||||
export const useApraisalStore = defineStore('appraisal', () => {
|
export const useApraisalStore = defineStore('appraisal', () => {
|
||||||
const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(cacheDuration);
|
const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(CACHE_DURATION);
|
||||||
|
|
||||||
const getPricesUncached = getMammonPrices;
|
const getPricesUncached = getMammonPrices;
|
||||||
|
|
||||||
@@ -32,8 +32,8 @@ export const useApraisalStore = defineStore('appraisal', () => {
|
|||||||
if (uncached.length > 0) {
|
if (uncached.length > 0) {
|
||||||
const batches: Promise<MarketTypePrice[]>[] = [];
|
const batches: Promise<MarketTypePrice[]>[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < uncached.length; i += batchSize) {
|
for (let i = 0; i < uncached.length; i += BATCH_SIZE) {
|
||||||
batches.push(getPricesUncached(uncached.slice(i, i + batchSize)));
|
batches.push(getPricesUncached(uncached.slice(i, i + BATCH_SIZE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const prices = (await Promise.all(batches)).flat();
|
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 = {
|
export type MarketType = MarketTypeResponse;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cache = new Map<number, MarketType>(); // TODO move to pinia store
|
const cache = new Map<number, MarketType>(); // TODO move to pinia store
|
||||||
|
|
||||||
const fetchType = (id: number): Promise<MarketType> => {
|
const BATCH_SIZE = 100;
|
||||||
if (cache.has(id)) {
|
|
||||||
return Promise.resolve(cache.get(id)!);
|
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 batches: Promise<MarketType[]>[] = [];
|
||||||
const { type_id, ...rest } = r.data;
|
for (let i = 0; i < missing.length; i += BATCH_SIZE) {
|
||||||
const marketType: MarketType = { id: type_id, ...rest };
|
batches.push(marketApi.findTypes(missing.slice(i, i + BATCH_SIZE)).then(r => r.data));
|
||||||
cache.set(id, marketType);
|
}
|
||||||
return marketType;
|
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];
|
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 [];
|
return [];
|
||||||
}
|
}
|
||||||
const ids = types.filter((t): t is number => typeof t === 'number');
|
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
|
export const searchMarketTypes = async (_search: string): Promise<MarketType[]> => {
|
||||||
2,
|
|
||||||
2157,
|
|
||||||
2159,
|
|
||||||
2339,
|
|
||||||
2160,
|
|
||||||
211,
|
|
||||||
1016,
|
|
||||||
339,
|
|
||||||
2290,
|
|
||||||
357,
|
|
||||||
1530,
|
|
||||||
359,
|
|
||||||
1531,
|
|
||||||
1532,
|
|
||||||
1533,
|
|
||||||
358
|
|
||||||
]
|
|
||||||
|
|
||||||
export const searchMarketTypes = async (search: string): Promise<MarketType[]> => {
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ watchEffect(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
|
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
|
||||||
<div class="fake-input">
|
<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" />
|
<input type="text" v-model="name" @keyup.enter="submit" @keyup.down="moveDown" @keyup.up="moveUp" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">
|
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">
|
||||||
|
|||||||
Reference in New Issue
Block a user