NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name HitBTC extract payments // @namespace https://openuserjs.org//users/codexus // @version 0.1 // @description Extract payments into CSV // @license GPL-3.0-or-later // @author JO // @match https://hitbtc.com/reports/history // @grant GM_notification // @grant window.focus // @grant document // @require https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js // ==/UserScript== let csrf = document.getElementsByTagName("body")[0].getAttribute("data-csrftoken"); function sleep (ms) {return new Promise((resolve) => setTimeout(resolve, ms))}; function end_of_month (date, month_offset=0) { return new Date(date.getFullYear(), date.getMonth() + 1 + month_offset, 0); }; function flatten (data) { var result = {}; function recurse (cur, prop) { if (Object(cur) !== cur) { result[prop] = cur; } else if (Array.isArray(cur)) { for(var i=0, l=cur.length; i<l; i++) recurse(cur[i], prop + "[" + i + "]"); if (l == 0) result[prop] = []; } else { var isEmpty = true; for (var p in cur) { isEmpty = false; recurse(cur[p], prop ? prop+"."+p : p); } if (isEmpty && prop) result[prop] = {}; } } recurse(data, ""); return result; } function to_csv({ list, order = null, sep = '\t', replace = {} }) { order = order || Object.keys(list[0]); let date_replacer = x => (x) ? x.toISOString().replace('T', ' ').replace(/\.[0-9]{3}Z/g, '') : ''; let csv = [order.join(sep)]; for (let o of list) { let row = []; for (let k of order) { for (let rem in replace){ if (typeof o[k] == 'string') o[k] = o[k].replace(rem, replace[rem]); }; if (k.toLowerCase().includes("date")) row.push(date_replacer(o[k])) else row.push(o[k]) }; csv.push(row.join(sep)) } return csv.join('\n') } function write_file({ name, content }) { let a = document.createElement("a"); a.href = `data:text,${content}`; //content a.download = name; //file name a.click(); } function notify({text, title, timeout, onclick, image}){ GM_notification( { text: text, title: 'HitBTC extract' || title, timeout:3000 || timeout, image: 'https://i.stack.imgur.com/geLPT.png' || image, onclick: function () { console.log ("Notice clicked."); window.focus (); } || onclick }) } function extract_page(data){ if (!data.transactions || !data.transactions.data) return [] let result = data.transactions.data.map(function(o){ ["created", "finished"].forEach(k=>{ o[`date${k.charAt(0).toUpperCase() + k.slice(1)}`]=new Date(o[k]*1000); delete o[k]; }); for (let k of ['amountStr', 'hashStr', 'detailStr', 'idStr']) o[k] && delete o[k]; return o; }); return result; } async function fetch_page ({start_date, end_date, page=1}){ let t = new Date(); notify( {text: `Downloading items #${start_date} (page ${page})`}) try{ console.log(start_date, end_date, page); let url = `https://hitbtc.com/reports/get-payment-history`; if (!end_date) end_date = end_of_month(new Date(start_date)).toLocaleDateString('fr-CA'); let form = new FormData(), params = { page: page, date_from: start_date, date_till: end_date, currency_code: "", period: "on", items: 100, __csrf__: csrf }; for (let p in params) form.set(p, params[p]); let data = await axios.post(url, form).then(r=>r.data); notify( {text: `${new Date()-t}ms for #${start_date} (page ${page})`}) if (data && data.status=='ok') { return data.data ;} else throw new Error(`Error in downloading page ${start_date}}`); } catch(err) {console.log(err); return {}}; } async function fetch_all({start_date="2017-10-01", end_date="2019-02-01", wait=500, max=1}={}) { if (!end_date) end_date = new Date().toLocaleDateString('fr-CA'); let p = [], p1 = await fetch_page({start_date, end_date, page:1}); p.push(extract_page(p1)); if (p1.transactions && !p1.transactions.isLast) { for (let i=2 ; i<=max ; i++) { await sleep(wait); let page = await fetch_page({start_date, end_date, page:i}); p.push(extract_page(page)); if (page.transactions.isLast) break } } let data = await Promise.all(p).then(arr=>Array.concat(...arr)); console.log(data) notify({text: `Fetched ${data.length} items`}); let csv = to_csv({ list: data, sep: ",", replace: {'&mdash':'-', '+':'+', ";":' ', "-":'-', "\n": ' ', ',': ""} }); write_file({ name: "payments.csv", content: csv }); }; fetch_all()