├── .gitignore ├── public ├── zomato16.png ├── zomato24.png ├── zomato32.png ├── zomato48.png ├── zomato128.png ├── loading-buffering.gif ├── popup.html └── manifest.json ├── readme-pics ├── z1.png ├── z2.png └── z3.png ├── src ├── background.ts ├── __tests__ │ └── sum.ts ├── content_script.tsx ├── options.tsx ├── popup.scss ├── popup.tsx └── api.ts ├── jest.config.js ├── webpack ├── webpack.prod.js ├── webpack.dev.js └── webpack.common.js ├── .vscode ├── settings.json └── tasks.json ├── tsconfig.json ├── LICENSE ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules/ 3 | dist/ 4 | tmp/ 5 | package-lock.json -------------------------------------------------------------------------------- /public/zomato16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/zomato16.png -------------------------------------------------------------------------------- /public/zomato24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/zomato24.png -------------------------------------------------------------------------------- /public/zomato32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/zomato32.png -------------------------------------------------------------------------------- /public/zomato48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/zomato48.png -------------------------------------------------------------------------------- /readme-pics/z1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/readme-pics/z1.png -------------------------------------------------------------------------------- /readme-pics/z2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/readme-pics/z2.png -------------------------------------------------------------------------------- /readme-pics/z3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/readme-pics/z3.png -------------------------------------------------------------------------------- /public/zomato128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/zomato128.png -------------------------------------------------------------------------------- /public/loading-buffering.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpgupt/zomato-spending-calculator/HEAD/public/loading-buffering.gif -------------------------------------------------------------------------------- /src/background.ts: -------------------------------------------------------------------------------- 1 | // function polling() { 2 | // // console.log("polling"); 3 | // setTimeout(polling, 1000 * 30); 4 | // } 5 | 6 | // polling(); 7 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "roots": [ 3 | "src" 4 | ], 5 | "transform": { 6 | "^.+\\.ts$": "ts-jest" 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /webpack/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production' 6 | }); -------------------------------------------------------------------------------- /webpack/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | devtool: 'inline-source-map', 6 | mode: 'development' 7 | }); -------------------------------------------------------------------------------- /src/__tests__/sum.ts: -------------------------------------------------------------------------------- 1 | // import { sum } from "../sum"; 2 | 3 | // test("1 + 1 = 2", () => { 4 | // expect(sum(1, 1)).toBe(2); 5 | // }); 6 | 7 | // test("1 + 2 != 2", () => { 8 | // expect(sum(1, 2)).not.toBe(2); 9 | // }); 10 | -------------------------------------------------------------------------------- /public/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |Zomato Home is open
77 |You are currently Signed In to Zomato Website
78 | {isError &&Error while fetching data
} 79 |Total Amount Spent :
80 | {isLoading ? <> (Fetching Data....) > : renderAmount(totalCost)}
81 |
Zomato Home is open
85 |You are not signed in , please sign in to Zomato to continue.
86 |Zomato Homepage is not open
90 |Open www.zomato.com on your browser, then use this extension
91 |Amount Spent in different Currencies
114 | {Object.keys(amount).map((key) => { 115 | return{key} {amount[key]}
116 | })} > 117 | } 118 | }; 119 | -------------------------------------------------------------------------------- /src/api.ts: -------------------------------------------------------------------------------- 1 | interface costStruct { 2 | [key: string]: number 3 | } 4 | 5 | export const makeApiCalls = async (cookies: chrome.cookies.Cookie[]) => { 6 | try { 7 | const cookieMap: { [name: string]: string } = {}; 8 | cookies.forEach(cookie => { 9 | cookieMap[cookie.name] = cookie.value; 10 | }); 11 | const myHeaders = new Headers(); 12 | myHeaders.append("authority", "www.zomato.com"); 13 | myHeaders.append("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"99\", \"Google Chrome\";v=\"99\""); 14 | myHeaders.append("x-zomato-csrft", cookieMap?.csrf); 15 | myHeaders.append("sec-ch-ua-mobile", "?1"); 16 | myHeaders.append("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Mobile Safari/537.36"); 17 | myHeaders.append("sec-ch-ua-platform", "\"Android\""); 18 | myHeaders.append("accept", "*/*"); 19 | myHeaders.append("sec-fetch-site", "same-origin"); 20 | myHeaders.append("sec-fetch-mode", "cors"); 21 | myHeaders.append("sec-fetch-dest", "empty"); 22 | myHeaders.append("accept-language", "en-US,en;q=0.9"); 23 | myHeaders.append("cookie", `fbcity=${cookieMap?.fbcity}; fre=${cookieMap?.fre}; rd=${cookieMap?.rd}; zl=${cookieMap.zl}; fbtrack=${cookieMap?.fbtrack}; _ga=${cookieMap?._ga}; _gid=${cookieMap?._gid}; _gcl_au=${cookieMap?._gcl_au}; _fbp=${cookieMap?._fbp}; G_ENABLED_IDPS=${cookieMap?.G_ENABLED_IDPS}; zhli=${cookieMap?.zhli}; g_state=${cookieMap?.g_state}; ltv=${cookieMap?.ltv}; lty=${cookieMap?.lty}; locus=${cookieMap?.locus}; squeeze=${cookieMap?.squeeze}; orange=${cookieMap?.orange}; csrf=${cookieMap?.csrf}; PHPSESSID=${cookieMap?.PHPSESSID}; AWSALBTG=${cookieMap?.AWSALBTG}; AWSALBTGCORS=${cookieMap?.AWSALBTGCORS}; fre=${cookieMap?.fre}; rd=${cookieMap?.rd}; AWSALBTG=${cookieMap?.AWSALBTG}; AWSALBTGCORS=${cookieMap?.AWSALBTGCORS}`); 24 | 25 | const requestOptions: RequestInit = { 26 | method: 'GET', 27 | headers: myHeaders, 28 | redirect: 'follow' 29 | }; 30 | 31 | const results: costStruct = {}; 32 | const stopDate = await getStopDate(); 33 | 34 | let stop = false; 35 | 36 | for (let index = 0; ; index++) { 37 | // const response = await fetch(`https://www.zomato.com/webroutes/user/orders?page=${page}`, requestOptions); 38 | if (stop) { 39 | break; 40 | } 41 | if (index > 1000) { 42 | break; 43 | } 44 | const pages = []; let count = 1; 45 | while (count <= 10) { 46 | pages.push(index * 10 + count); 47 | count++; 48 | } 49 | 50 | const batchData = await Promise.all(pages.map(async (page): Promise<[boolean,costStruct]>=> { 51 | let total: costStruct = {}; 52 | const response = await fetchWrrapper(`https://www.zomato.com/webroutes/user/orders?page=${page}`, requestOptions); 53 | 54 | if (response === "") { 55 | return [false, {}]; 56 | } 57 | 58 | const data = JSON.parse(response)?.entities?.ORDER; 59 | if (JSON.stringify(data) === JSON.stringify([])) { 60 | stop = true; 61 | return [false, total]; 62 | } 63 | 64 | for (const key in data) { 65 | if (stopDate.getTime() > new Date().getTime()) { 66 | if (data[key].paymentStatus) { 67 | const [currency, amount] = separateCurrencyFromCost(data[key].totalCost); 68 | total[currency] = (total[currency] || 0) + parseFloat(amount); 69 | } 70 | } 71 | else { 72 | const value = data[key]; 73 | const orderDate = new Date(value.orderDate.split("at")[0].trim()); 74 | if (orderDate.getTime() < stopDate.getTime()) { 75 | stop = true; 76 | } 77 | else { 78 | if (data[key].paymentStatus) { 79 | const [currency, amount] = separateCurrencyFromCost(data[key].totalCost); 80 | total[currency] = (total[currency] || 0) + parseFloat(amount); 81 | } 82 | } 83 | } 84 | } 85 | 86 | return [true, total]; 87 | })); 88 | 89 | batchData.forEach(data => { 90 | const [status, total] = data; 91 | if (status) { 92 | for (const key in total) { 93 | results[key] = (results[key] || 0) + total[key]; 94 | } 95 | } 96 | }); 97 | } 98 | return results; 99 | } 100 | catch (e) { 101 | console.log(e); 102 | throw new Error("Error while making api calls to zomato"); 103 | } 104 | } 105 | 106 | const getStopDate = async () => { 107 | let dateOption: string; 108 | const items = await chrome.storage.sync.get("dateOption"); 109 | dateOption = items.dateOption; 110 | let stopDate: Date; 111 | const presentDay = new Date(); 112 | 113 | switch (dateOption) { 114 | case "For All Time": 115 | stopDate = new Date(presentDay.getFullYear(), presentDay.getMonth(), presentDay.getDate() + 1); 116 | break; 117 | case "This Month": 118 | stopDate = new Date(presentDay.getFullYear(), presentDay.getMonth(), 1); 119 | break; 120 | case "This Year": 121 | stopDate = new Date(presentDay.getFullYear(), 0, 1); 122 | break; 123 | default: 124 | stopDate = new Date(presentDay.getFullYear(), presentDay.getMonth(), presentDay.getDate() + 1); 125 | } 126 | 127 | return stopDate; 128 | } 129 | 130 | const fetchWrrapper = async (url: string, options: RequestInit) => { 131 | return fetch(url, options).then(response => { 132 | return response.text(); 133 | }).catch(_ => { 134 | return ""; 135 | }); 136 | } 137 | 138 | const separateCurrencyFromCost = (cost: string) => { 139 | const firstDigitIndex = cost.search(/\d/); 140 | const currency = cost.substring(0, firstDigitIndex).trim(); 141 | const amount = cost.substring(firstDigitIndex).trim(); 142 | return [currency, amount]; 143 | }; --------------------------------------------------------------------------------