Files
keyhunter-parser/_agent_dash.js

72 lines
3.0 KiB
JavaScript

async function jget(u){const r=await fetch(u);return r.json();}
async function post(u){const r=await fetch(u,{method:'POST'});return r.json();}
async function refresh(){
try{
const s=await jget('/api/stats');
el('m-total').textContent=s.total.toLocaleString('ru');
el('m-today').textContent=s.today.toLocaleString('ru');
const alive=Object.values(s.engines).filter(e=>e.alive).length;
el('m-eng').textContent=alive+' / '+Object.keys(s.engines).length;
el('m-ts').textContent=s.ts;
// движки
const box=el('eng');box.innerHTML='';
for(const [id,e] of Object.entries(s.engines)){
const c=document.createElement('div');c.className='card';
c.innerHTML=`<div><span class="dot ${e.alive?'on':'off'}"></span><b>${id}</b><div style="color:var(--dim);font-size:12px">${e.desc}${e.auto?' · auto':''}</div></div>`;
const btn=document.createElement('button');
btn.textContent=e.alive?'стоп':'старт';
if(e.alive)btn.className='stop';
btn.onclick=async()=>{e.alive?await post('/api/engine/'+id+'/stop'):await post('/api/engine/'+id+'/start');refresh();};
c.appendChild(btn);box.appendChild(c);
}
// статусы
const st=el('t-status');st.innerHTML='';
const mx=Math.max(...s.by_status.map(x=>x.n),1);
for(const r of s.by_status){
const tr=document.createElement('tr');
tr.innerHTML=`<td><span class="badge b-${r.status}">${r.status}</span></td><td>${r.n.toLocaleString('ru')}</td>
<td style="width:40%"><div class="bar"><i style="width:${(100*r.n/mx).toFixed(0)}%"></i></div></td>`;
st.appendChild(tr);
}
// провайдеры
const pv=el('t-prov');pv.innerHTML='';
for(const r of s.by_prov){
const tr=document.createElement('tr');
tr.innerHTML=`<td>${r.prov}</td><td>${r.n.toLocaleString('ru')}</td>`;
tr.style.cursor='pointer';
tr.onclick=()=>{el('f-prov').value=r.prov;loadKeys();};
pv.appendChild(tr);
}
loadKeys();
loadLog();
}catch(e){console.error(e);}
}
async function loadKeys(){
const st=el('f-status').value,pv=el('f-prov').value,lim=el('f-limit').value||50;
const d=await jget(`/api/keys?status=${st}&prov=${pv}&limit=${lim}`);
const t=el('t-keys');t.innerHTML='';
for(const r of d.rows){
const tr=document.createElement('tr');
tr.innerHTML=`<td><span class="badge b-${r.status}">${r.status}</span></td><td>${r.prov}</td>
<td title="${r.val}">${r.val}</td><td title="${r.repo||''}">${r.repo||''}</td><td>${r.found||''}</td>`;
t.appendChild(tr);
}
el('k-count').textContent=d.rows.length+' показано';
}
async function loadLog(){
const r=await fetch('/api/log?engine='+el('f-log').value);
el('log').textContent=await r.text();
el('log').scrollTop=el('log').scrollHeight;
}
function el(id){return document.getElementById(id);}
function exportKeys(){const st=el('f-status').value,pv=el('f-prov').value;
window.open(`/api/export?status=${st}&prov=${pv}`,'_blank');}
refresh();
setInterval(refresh,5000);