Skip to content

Commit

Permalink
Merge pull request #206 from yssk22/develop
Browse files Browse the repository at this point in the history
[expo] support cart scraping.
  • Loading branch information
yssk22 authored Jan 6, 2025
2 parents 4cb0ac8 + 76b90c5 commit 8c3a937
Show file tree
Hide file tree
Showing 9 changed files with 2,705 additions and 8 deletions.
3 changes: 3 additions & 0 deletions expo/assets/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
"Ordered On": {
"ja": "注文日"
},
"Already In Your Cart": {
"ja": "すでにカートに入っています"
},
"FC credentials will be used to fetch your purchase history from elineupmall.": {
"ja": "ファンクラブの認証情報を使用して、Elineup!Mallから購入履歴を取得します。"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ export function ElineupMallLimitedTimeItemListItem({
);
const dateString = date.toDateString(item.orderEndAt);
const orderedAt =
purchaseHistoryItem !== undefined ? date.toDateString(purchaseHistoryItem!.order.orderedAt) : undefined;
purchaseHistoryItem !== undefined && purchaseHistoryItem.order.status !== 'cart'
? date.toDateString(purchaseHistoryItem!.order.orderedAt)
: undefined;
const isInCart = purchaseHistoryItem !== undefined && purchaseHistoryItem.order.status === 'cart';
const imageUrl = item.images[0].url;
return (
<>
Expand Down Expand Up @@ -107,6 +110,17 @@ export function ElineupMallLimitedTimeItemListItem({
</Text>
</View>
)}
{isInCart && (
<View style={styles.metadataRow}>
<Text
style={[styles.metadataValue, { fontWeight: 'bold', color, backgroundColor: contrast }]}
numberOfLines={1}
ellipsizeMode="tail"
>
{t('Already In Your Cart')}
</Text>
</View>
)}
</View>
</View>
</ListItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ export default class ElineupMallFileFetcher implements ElineupMallFetcher {
authResultHTMLPath: string;
orderListHTMLPath: string;
orderDetailHTMLPath: string;
cartHTMLPath: string;
};

constructor(paths: { authResultHTMLPath: string; orderListHTMLPath: string; orderDetailHTMLPath: string }) {
constructor(paths: {
authResultHTMLPath: string;
orderListHTMLPath: string;
orderDetailHTMLPath: string;
cartHTMLPath: string;
}) {
this.paths = paths;
}

Expand All @@ -28,6 +34,10 @@ export default class ElineupMallFileFetcher implements ElineupMallFetcher {
return await this.readFile(this.paths.orderDetailHTMLPath);
}

async fetchCartHtml(): Promise<string> {
return await this.readFile(this.paths.cartHTMLPath);
}

async readFile(path: string): Promise<string> {
try {
return await readFile(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export default class ElineupMallHttpFetcher implements ElineupMallFetcher {
return await this.fetch(`https://www.elineupmall.com/index.php?dispatch=orders.details&order_id=${id}`);
}

async fetchCartHtml(): Promise<string> {
return await this.fetch(`https://www.elineupmall.com/cart/`);
}

async fetch(url: string): Promise<string> {
const resp = await fetch(url, {
credentials: 'include'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ describe('ElineupMallSiteScraper', () => {
new ElineupMallFileFetcher({
authResultHTMLPath: path.join(__dirname, './testdata/auth_success.html'),
orderListHTMLPath: '',
orderDetailHTMLPath: ''
orderDetailHTMLPath: '',
cartHTMLPath: ''
})
);
const ok = await scraper.authenticate('mizuki', 'fukumura');
Expand All @@ -22,7 +23,8 @@ describe('ElineupMallSiteScraper', () => {
new ElineupMallFileFetcher({
authResultHTMLPath: path.join(__dirname, './testdata/auth_error.html'),
orderListHTMLPath: '',
orderDetailHTMLPath: ''
orderDetailHTMLPath: '',
cartHTMLPath: ''
})
);
const ok = await scraper.authenticate('mizuki', 'fukumura');
Expand All @@ -35,7 +37,8 @@ describe('ElineupMallSiteScraper', () => {
new ElineupMallFileFetcher({
authResultHTMLPath: '',
orderListHTMLPath: path.join(__dirname, './testdata/order_list.html'),
orderDetailHTMLPath: path.join(__dirname, './testdata/order_detail.html')
orderDetailHTMLPath: path.join(__dirname, './testdata/order_detail.html'),
cartHTMLPath: ''
})
);
const list = await scraper.getOrderList(new Date('2024-08-04T00:00:00+09:00'));
Expand Down Expand Up @@ -65,4 +68,29 @@ describe('ElineupMallSiteScraper', () => {
'https://www.elineupmall.com/c720/c2784/202412-dvdjuicejuice-2024-juicejuice-fc2024-alp84jmu/'
);
});

it('cart', async () => {
const scraper = new ElineupMallSiteScraper(
new ElineupMallFileFetcher({
authResultHTMLPath: '',
orderListHTMLPath: '',
orderDetailHTMLPath: '',
cartHTMLPath: path.join(__dirname, './testdata/cart.html')
})
);
const cart = await scraper.getCart();
expect(cart.details.length).toBe(2);
expect(cart.details[0].link).toBe('https://www.elineupmall.com/c671/c181/c197/c199/25-t-f6pdtyr4/');
expect(cart.details[0].code).toBe('134585');
expect(cart.details[0].num).toBe(1);
expect(cart.details[0].unitPrice).toBe(4500);
expect(cart.details[0].totalPrice).toBe(4500);
expect(cart.details[1].link).toBe(
'https://www.elineupmall.com/c671/c181/c197/c201/juicejuice-shop-2024-hp-color1l-11128-0224-cxwz7rmy/'
);
expect(cart.details[1].code).toBe('403661');
expect(cart.details[1].num).toBe(1);
expect(cart.details[1].unitPrice).toBe(160);
expect(cart.details[1].totalPrice).toBe(160);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,48 @@ export default class ElineupMallSiteScraper implements ElineupMallScraper {
return d.name !== '' && d.num > 0 && d.unitPrice > 0;
});
}

public async getCart(): Promise<ElineupMallOrder> {
const html = await this.fetcher.fetchCartHtml();
const root = parse(html);
const details: ElineupMallOrderDetail[] = root.querySelectorAll('table.ty-cart-content > tbody > tr').map((row) => {
const description = row.querySelector('td.ty-cart-content__description');
const a = description?.querySelector('a.ty-cart-content__product-title');
if (a === null || a === undefined) {
return {
name: '',
num: 0,
link: '',
code: '',
unitPrice: 0,
totalPrice: 0
};
}
const name = a.innerHTML.trim();
const link = a.getAttribute('href') ?? '';
const code =
description?.querySelector('div.ty-cart-content__sku > span')?.text.replaceAll('&nbsp;', '').trim() ?? '';
const unitPriceText = row.querySelector('td.ty-cart-content__price > span')?.text.replaceAll(',', '');
const unitPrice = parseInt(unitPriceText ?? '0', 10);
const qtyInput = row.querySelector('td.ty-cart-content__qty input.ty-value-changer__input');
const num = parseInt(qtyInput?.getAttribute('value') ?? '0', 10);
return {
name,
num,
link,
code,
unitPrice,
totalPrice: unitPrice * num
};
});

return {
id: 'cart',
status: 'cart',
orderedAt: new Date(),
details
};
}
}

function toOrderStatus(statusString: string | undefined): ElineupMallOrderStatus {
Expand Down
Loading

0 comments on commit 8c3a937

Please sign in to comment.