<!doctype html>
< html class = "no-js" lang = "en-US" >
< head >
< meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width" >
< title > HeroUnion - Open source web crawler union.< / title >
< meta name = "author" content = "filesite.io" >
< meta name = "description" content = "HeroUnion: Open source web crawler union." >
< style >
*,body{margin:0;padding:0}
body{padding:8px;max-width:640px;margin:0 auto}
h1{font-size:2em;font-weight:500}
small{font-size:65%;font-weight:400}
pre{background-color:#DDD;padding-bottom:3px;padding-right:3px;border-radius:0 5px 0 5px;max-width:480px}
code{display:block;background-color:#EEE;padding:4px}
dt{background-color:#EEE;padding:4px 6px}
dd{text-indent:1em;margin:4px 0 8px 0}
li{margin-left:1em}
footer{padding-bottom:2em}
.text-center{text-align:center}
.text-right{text-align:right}
.mt-d5{margin-top:.5em}
.mt-1{margin-top:1em}
.mt-2{margin-top:2em}
.mt-4{margin-top:4em}
.mx-d2{margin-left:.5em;margin-right:.2em}
.stats{background-color:#EEE;padding:10px 10px 4px 10px}
.col{display:inline-block;padding:13px 4px;width:20%;background:#444;color:#FFF;margin-right:4px;margin-bottom:6px;text-align:center}
.col strong{font-size:24px}
.col label{display:block;font-size:15px}
.info{background-color:darkblue}
.success{background-color:green}
.warning{background-color:orange;color:#444}
.danger{background-color:red}
.disable{background-color:gray}
@media(max-width:480px) {
h1 small{display:block}
}
< / style >
< / head >
< body >
< h1 class = "text-center" > HeroUnion< small > - Open source web crawler union< / small > < / h1 >
< hr class = "mt-d5" >
< p class = "text-right mt-d5" >
< a href = "/" class = "mx-d2" > 简体中文< / a >
< a href = "/en/" class = "mx-d2" > English< / a >
< / p >
< h3 class = "mt-1" > HeroUnion download< / h3 >
< p > < a href = "https://github.com/filesite-io/herounion" target = "_blank" > https://github.com/filesite-io/herounion< / a > < / p >
< h3 class = "mt-1" > HeroBot download< / h3 >
< p > < a href = "https://github.com/filesite-io/machete_hero" target = "_blank" > https://github.com/filesite-io/machete_hero< / a > < / p >
< h3 class = "mt-2" > HeroUnion Stats - It's running < span class = "run_time" > ...< / span > < / h3 >
< h4 class = "mt-d5" > Tasks Stats (Past < span class = "cache_time" > ...< / span > )< / h4 >
< div class = "stats taskStatus" >
< span class = "col" >
< strong class = "total" > ...< / strong >
< label > Total< / label >
< / span >
< span class = "col info" >
< strong class = "waiting" > ...< / strong >
< label > Waiting< / label >
< / span >
< span class = "col warning" >
< strong class = "running" > ...< / strong >
< label > Running< / label >
< / span >
< span class = "col success" >
< strong class = "done" > ...< / strong >
< label > Done< / label >
< / span >
< span class = "col danger" >
< strong class = "failed" > ...< / strong >
< label > Failed< / label >
< / span >
< / div >
< h4 class = "mt-d5" > Notify Stats (Past < span class = "cache_time" > ...< / span > )< / h4 >
< div class = "stats taskNotifyStatus" >
< span class = "col" >
< strong class = "total" > ...< / strong >
< label > Total< / label >
< / span >
< span class = "col success" >
< strong class = "done" > ...< / strong >
< label > Done< / label >
< / span >
< span class = "col danger" >
< strong class = "failed" > ...< / strong >
< label > Failed< / label >
< / span >
< / div >
< h4 class = "mt-d5" > Bot Stats< / h4 >
< div class = "stats heroStatus" >
< span class = "col" >
< strong class = "total" > ...< / strong >
< label > Total< / label >
< / span >
< span class = "col success" >
< strong class = "idle" > ...< / strong >
< label > Idle< / label >
< / span >
< span class = "col warning" >
< strong class = "busy" > ...< / strong >
< label > Busy< / label >
< / span >
< span class = "col disable" >
< strong class = "offline" > ...< / strong >
< label > Offline< / label >
< / span >
< / div >
< h4 class = "mt-d5" > JSON Data< / h4 >
< pre > < code id = "herounion_stats" > ...< / code > < / pre >
< h3 class = "mt-2" > Bots< / h3 >
< dl class = "mt-d5" id = "herobots" > ...< / dl >
< h3 class = "mt-2" > Covenant of the Alliance< / h3 >
< p class = "mt-1" > Please abide by the following conventions and stick to it for a better tomorrow for yourself and the whole society! < / p >
< ul class = "mt-d5" >
< li > Comply with local/national laws and regulations< / li >
< li > Information protected by law will not be crawled (for example: personal privacy data mobile phone number, ID number, etc.)< / li >
< li > Data that requires login or VIP status to access will not be crawled< / li >
< li > Data that is explicitly prohibited from being collected by the target website will not be crawled< / li >
< li > The commercial core data of the target website is not crawled< / li >
< li > Low concurrency, low frequency, does not affect the normal operation of the target website< / li >
< / ul >
< footer class = "mt-4" >
< p >
< strong > Disclaimer:< / strong >
< br > HeroUnion< strong > is only responsible for the scheduling of crawlers and tasks< / strong > . The contracts supported by crawlers and the specific content of tasks have nothing to do with the alliance.
< / p >
< p class = "mt-2 text-center" > © copyright < a href = "https://filesite.io" target = "_blank" > FileSite.io< / a > < / p >
< / footer >
< script src = "/js/jquery-3.7.1.min.js" > < / script >
< script type = "text/javascript" >
var formatSeconds = function(secs) {
var str = secs + '秒';
if (secs > 86400) {
str = Math.floor(secs/86400) + ' days';
}else if (secs > 3600) {
str = Math.floor(secs/3600) + ' hours';
}else if (secs > 300) {
str = Math.floor(secs/60) + ' minutes';
}else if (secs > 86400*365) {
str = Math.floor(secs/86400/365) + ' years'
+ Math.floor( (secs - Math.floor(secs/86400/365)) / 86400 ) + ' days';
}
return str;
};
var renderStats = function(parentCls, data) {
for (var key in data) {
$('.' + parentCls + ' .'+key).text(data[key]);
}
};
var htmlspecialchars = function(str) {
return str.replace('& ', '& ').replace('< ', '< ').replace('>', '> ');
};
var renderHeros = function(heros) {
if (!heros || heros.length == 0) {
$('#herobots').text('There is no bot online.');
return;
}
var txtStatus = {idle: 'Idle', busy: 'Busy', offline: 'Offline'};
var html = '', item;
for (var index in heros) {
item = heros[index];
html += '< dt > ' + htmlspecialchars(item['name']) + ' < small > '
+ txtStatus[item['status']] + '< / small > < / dt > ';
html += '< dd > '
+ htmlspecialchars(item['description'])
+ '< br > Platforms: ' + JSON.stringify(item['platforms'])
+ ', Contracts: ' + JSON.stringify(item['contracts'])
+ ', Contact: ' + htmlspecialchars(item['contact'])
+ '< / dd > ';
}
$('#herobots').html(html);
};
var loadUnionStats = function() {
$('.run_time').text('...');
var api = '/api/stats/';
$.ajax({
url: api,
method: 'GET',
dataType: 'json'
}).done(function(data) {
$('#herounion_stats').text(JSON.stringify(data, null, 4));
$('.run_time').text( formatSeconds(data.run_seconds) );
$('.cache_time').text( formatSeconds(data.cache_time) );
renderStats('taskStatus', data.taskStatus);
renderStats('taskNotifyStatus', data.taskNotifyStatus);
renderStats('heroStatus', data.heroStatus);
});
};
var loadHeros = function() {
$('#herobots').text('...');
var api = '/api/heros/';
$.ajax({
url: api,
method: 'GET',
dataType: 'json'
}).done(function(data) {
renderHeros(data);
});
};
//init
loadUnionStats();
loadHeros();
setInterval(loadUnionStats, 20000);
< / script >
< / body >
< / html >