jef / streetmerchant

🤖 The world's easiest, most powerful stock checker
https://jef.buzz/streetmerchant
MIT License
4.96k stars 1.31k forks source link

Adding Amazon JP #918

Closed NAlexH2 closed 3 years ago

NAlexH2 commented 3 years ago

Description

Adding amazon.co.jp. Doing this because people I know (mostly expats) are having a terribly difficult time getting their hands on PS5 of any kind and the scalping is absolutely NUTS right now in Japan over these 2 things.

Possible solution

I've already made the changes to the src/store/model/index.ts and added the amazon-jp.ts. I've also tested with the test:series on a random jp item and it seems to be working as desired. Not 100% certain how you want this so here's just the copied code from each file.

amazon-jp.ts

import {Store} from './store';

export const AmazonJp: Store = {
    backoffStatusCodes: [403, 429, 503],
    labels: {
        captcha: {
            container: 'body',
            text: ['enter the characters you see below']
        },
        inStock: {
            container: '#combinedBuyBox',
            text: ['add to cart']
        },
        maxPrice: {
            container: 'span[class*="PriceString"]'
        }
    },
    links: [
        {
            brand: 'test:brand',
            model: 'test:model',
            series: 'test:series',
            url: 'https://www.amazon.co.jp/-/en/Truitt-Angela/dp/B08NDT3LGC'
        },
        {
            brand: 'sony',
            cartUrl:
                'https://www.amazon.co.jp/gp/aws/cart/add.html?ASIN.1=B08GGGBKRQ&Quantity.1=1',
            model: 'ps5 console',
            series: 'sonyps5c',
            url: 'https://www.amazon.co.jp/-/en/dp/B08GGGBKRQ'
        },  
        {
            brand: 'sony',
            cartUrl:
                'https://www.amazon.co.jp/gp/aws/cart/add.html?ASIN.1=B08GGCGS39&Quantity.1=1',
            model: 'ps5 digital',
            series: 'sonyps5de',
            url: 'https://www.amazon.co.jp/gp/product/B08GGCGS39'
        }
    ],
    name: 'amazon-jp'
};

index.ts with AmazonJp and amazon-jp

import {config, defaultStoreData} from '../../config';
import {Adorama} from './adorama';
import {Alternate} from './alternate';
import {AlternateNL} from './alternate-nl';
import {Amazon} from './amazon';
import {AmazonCa} from './amazon-ca';
import {AmazonDe} from './amazon-de';
import {AmazonEs} from './amazon-es';
import {AmazonFr} from './amazon-fr';
import {AmazonNl} from './amazon-nl';
import {AmazonUk} from './amazon-uk';
import {AmazonJp} from './amazon-jp';
import {Amd} from './amd';
import {AmdDe} from './amd-de';
import {Aria} from './aria';
import {Arlt} from './arlt';
import {Asus} from './asus';
import {AsusDe} from './asus-de';
import {Azerty} from './azerty';
import {BAndH} from './bandh';
import {BestBuy} from './bestbuy';
import {BestBuyCa} from './bestbuy-ca';
import {Box} from './box';
import {CanadaComputers} from './canadacomputers';
import {Caseking} from './caseking';
import {Ccl} from './ccl';
import {Computeruniverse} from './computeruniverse';
import {Coolblue} from './coolblue';
import {Coolmod} from './coolmod';
import {Corsair} from './corsair';
import {Currys} from './currys';
import {Cyberport} from './cyberport';
import {Ebuyer} from './ebuyer';
import {Evga} from './evga';
import {EvgaEu} from './evga-eu';
import {Galaxus} from './galaxus';
import {Game} from './game';
import {Gamestop} from './gamestop';
import {Kabum} from './kabum';
import {Mediamarkt} from './mediamarkt';
import {MemoryExpress} from './memoryexpress';
import {MicroCenter} from './microcenter';
import {Mindfactory} from './mindfactory';
import {Newegg} from './newegg';
import {NeweggCa} from './newegg-ca';
import {Notebooksbilliger} from './notebooksbilliger';
import {Novatech} from './novatech';
import {Nvidia} from './nvidia';
import {NvidiaApi} from './nvidia-api';
import {OfficeDepot} from './officedepot';
import {Overclockers} from './overclockers';
import {PCComponentes} from './pccomponentes';
import {PlayStation} from './playstation';
import {Pny} from './pny';
import {ProshopDE} from './proshop-de';
import {ProshopDK} from './proshop-dk';
import {Saturn} from './saturn';
import {Scan} from './scan';
import {Store} from './store';
import {Target} from './target';
import {TopAchat} from './topachat';
import {Very} from './very';
import {VsGamers} from './vsgamers';
import {Walmart} from './walmart';
import {Xbox} from './xbox';
import {Zotac} from './zotac';
import {logger} from '../../logger';

export const storeList = new Map([
    [Adorama.name, Adorama],
    [Alternate.name, Alternate],
    [AlternateNL.name, AlternateNL],
    [Amazon.name, Amazon],
    [AmazonCa.name, AmazonCa],
    [AmazonDe.name, AmazonDe],
    [AmazonEs.name, AmazonEs],
    [AmazonFr.name, AmazonFr],
    [AmazonNl.name, AmazonNl],
    [AmazonUk.name, AmazonUk],
    [AmazonJp.name, AmazonJp],
    [Amd.name, Amd],
    [AmdDe.name, AmdDe],
    [Aria.name, Aria],
    [Arlt.name, Arlt],
    [Asus.name, Asus],
    [AsusDe.name, AsusDe],
    [Azerty.name, Azerty],
    [BAndH.name, BAndH],
    [BestBuy.name, BestBuy],
    [BestBuyCa.name, BestBuyCa],
    [Box.name, Box],
    [Caseking.name, Caseking],
    [CanadaComputers.name, CanadaComputers],
    [Ccl.name, Ccl],
    [Computeruniverse.name, Computeruniverse],
    [Coolblue.name, Coolblue],
    [Coolmod.name, Coolmod],
    [Corsair.name, Corsair],
    [Currys.name, Currys],
    [Cyberport.name, Cyberport],
    [Ebuyer.name, Ebuyer],
    [Evga.name, Evga],
    [EvgaEu.name, EvgaEu],
    [Galaxus.name, Galaxus],
    [Game.name, Game],
    [Gamestop.name, Gamestop],
    [Kabum.name, Kabum],
    [Mediamarkt.name, Mediamarkt],
    [MemoryExpress.name, MemoryExpress],
    [MicroCenter.name, MicroCenter],
    [Mindfactory.name, Mindfactory],
    [Newegg.name, Newegg],
    [NeweggCa.name, NeweggCa],
    [Notebooksbilliger.name, Notebooksbilliger],
    [Novatech.name, Novatech],
    [Nvidia.name, Nvidia],
    [NvidiaApi.name, NvidiaApi],
    [OfficeDepot.name, OfficeDepot],
    [Overclockers.name, Overclockers],
    [PCComponentes.name, PCComponentes],
    [PlayStation.name, PlayStation],
    [Pny.name, Pny],
    [ProshopDE.name, ProshopDE],
    [ProshopDK.name, ProshopDK],
    [Saturn.name, Saturn],
    [Scan.name, Scan],
    [Target.name, Target],
    [TopAchat.name, TopAchat],
    [Very.name, Very],
    [VsGamers.name, VsGamers],
    [Walmart.name, Walmart],
    [Xbox.name, Xbox],
    [Zotac.name, Zotac]
]);

const brands = new Set();
const models = new Set();
const series = new Set();
const stores = new Map();

function filterBrandsSeriesModels() {
    brands.clear();
    series.clear();
    models.clear();

    for (const store of storeList.values()) {
        for (const link of store.links) {
            brands.add(link.brand);
            series.add(link.series);
            models.add(link.model);
        }

        if (store.minPageSleep === undefined) {
            store.minPageSleep = defaultStoreData.minPageSleep;
        }

        if (store.maxPageSleep === undefined) {
            store.maxPageSleep = defaultStoreData.maxPageSleep;
        }
    }
}

function printConfig() {
    if (config.store.stores.length > 0) {
        logger.info(
            `ℹ selected stores: ${config.store.stores
                .map((store) => store.name)
                .join(', ')}`
        );
    }

    if (config.store.showOnlyBrands.length > 0) {
        logger.info(`ℹ selected brands: ${config.store.showOnlyBrands.join(', ')}`);
    }

    if (config.store.showOnlyModels.length > 0) {
        logger.info(
            `ℹ selected models: ${config.store.showOnlyModels
                .map((entry) => {
                    return entry.series
                        ? entry.name + ' (' + entry.series + ')'
                        : entry.name;
                })
                .join(', ')}`
        );
    }

    if (config.store.showOnlySeries.length > 0) {
        logger.info(`ℹ selected series: ${config.store.showOnlySeries.join(', ')}`);
    }
}

function warnIfStoreDeprecated(store: Store) {
    switch (store.name) {
        case 'nvidia':
        case 'nvidia-api':
            logger.warn(`${store.name} is deprecated in favor of bestbuy`);
            break;
        case 'evga':
            logger.warn(
                `${store.name} is deprecated since they only support queuing`
            );
            break;
        default:
    }
}

export function updateStores() {
    stores.clear();

    for (const storeData of config.store.stores) {
        const store = storeList.get(storeData.name);

        if (store) {
            warnIfStoreDeprecated(store);
            stores.set(storeData.name, store);
            store.minPageSleep = storeData.minPageSleep;
            store.maxPageSleep = storeData.maxPageSleep;
        } else {
            logger.warn(`No store named ${storeData.name}, skipping.`);
        }
    }

    filterBrandsSeriesModels();
    printConfig();
}

updateStores();

export function getAllBrands() {
    return Array.from(brands);
}

export function getAllSeries() {
    return Array.from(series);
}

export function getAllModels() {
    return Array.from(models);
}

export function getStores() {
    return stores;
}

export * from './store';
github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] commented 3 years ago

This issue has been closed because it is stale. Reopen if necessary.