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()