Nah, that's due to the fact that it rebuilds every night and sometimes the clearweb is not accessible.
The code is crude, but hey:
package.json:
{
"name": "trantor.is-langs",
"version": "1.0.0",
"main": "index.js",
"author": "X",
"license": "MIT",
"dependencies": {
"axios": "^0.21.1",
"axios-cookiejar-support": "^1.0.1",
"tough-cookie": "^4.0.0"
},
"scripts": {
"build": "node index.js"
}
}
index.js:
const fs = require('fs')
const axios = require('axios').default
const axiosCookieJarSupport = require('axios-cookiejar-support').default
const tough = require('tough-cookie')
const codes = [
'af',
'ar',
'bg',
'br',
'bs',
'ca',
'ceb',
'cs',
'cy',
'da',
'de',
'el',
'en',
'eo',
'es',
'et',
'fa',
'fi',
'fr',
'fy',
'ga',
'gd',
'gl',
'he',
'hi',
'hr',
'hu',
'ia',
'id',
'is',
'it',
'ja',
'ko',
'la',
'lt',
'mi',
'ml',
'ms',
'nl',
'nn',
'no',
'oc',
'pl',
'po',
'pt',
'ro',
'ru',
'sa',
'sco',
'sk',
'sl',
'sr',
'sv',
'ta',
'te',
'tl',
'tr',
'uk',
'und',
'vi',
'xh',
'zh',
]
const baseQueryParams = '?num=1&fmt=json&q=lang%3A'
axiosCookieJarSupport(axios)
const cookieJar = new tough.CookieJar()
const client = axios.create({
baseURL: 'https://trantor.is/search/',
jar: cookieJar,
withCredentials: true,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
},
})
let cache = {}
const cachePath = __dirname + '/dist/data.json'
if (fs.existsSync(cachePath)) {
cache = require(cachePath)
}
const saveLangs = (langs, refreshTime) => {
let langsHtml = ''
langs.forEach((lang) => {
langsHtml += `<div class="languageBox"><a href="https://trantor.is/search/?q=lang:${lang.code}" target="_blank" class="langLink">${lang.code} (${lang.count})</a></div>`
})
const bases = {
onion: 'http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion/',
clearweb: 'https://trantor.is/',
}
const html = `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Languages of Trantor.is</title>
<meta name="description" content="Languages of Trantor.is">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap" rel="stylesheet">
<style>
*, html, body {
font-family: 'Roboto', sans-serif;
}
.languageBox {
padding: 10px;
border: 1px solid #000;
margin: 10px;
}
.container {
max-width: 800px;
margin: 20px auto;
}
.languageSwitch {
cursor: pointer;
}
</style>
<script>
const bases = {
onion: 'http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion/',
clearweb: 'https://trantor.is/',
}
const switchBase = (to) => {
}
</script>
</head>
<body>
<div class="container">
<h2>Languages available on <a href="https://trantor.is/" class="langLink" target="_blank">Imperial Library of Trantor</a> [sorted by frequency]</h2>
<div>
Select link version:<br />
* <a class="languageSwitch" data-to="onion">Onion [${bases.onion}]</a><br />
* <a class="languageSwitch" data-to="clearweb">Clearweb [${bases.clearweb}]</a>
</div>
<div style="display: flex; flex-wrap: wrap; justify-content: space-between;">
${langsHtml}
</div>
${refreshTime ? `<div>Last refresh: ${new Date().toUTCString()}</div>` : ''}
<div>If you want the data, see: <a href="data.json" target="_blank">data.json</a> file</div>
</div>
<script>
document.querySelectorAll('.languageSwitch').forEach(languageSwitch =>
languageSwitch.addEventListener('click', (e) => {
const to = languageSwitch.dataset.to
const from = to === 'onion' ? 'clearweb' : 'onion'
document.querySelectorAll('.langLink').forEach(link => link.href = link.href.replace(bases[from], bases[to]))
})
)
</script>
</body>
</html>`
fs.writeFileSync(__dirname + '/dist/index.html', html)
}
const saveCache = () => {
fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2))
}
const generateLanguages = async () => {
let langs = []
for (let i = 0; i < codes.length; i++) {
const code = codes[i]
if (cache[code]) {
if (cache[code].time > new Date().getTime() - 3600 * 1000) {
langs.push(cache[code].data)
continue
}
}
console.log(`Obtaining data for language: ${code}`)
let json
try {
json = await client.get(baseQueryParams + code)
} catch (err) {
console.error(err.message)
throw err
}
langs.push({ code, count: json.data.found })
cache[code] = {
time: new Date().getTime(),
data: { code, count: json.data.found },
}
saveCache()
}
saveCache()
langs.sort((a, b) => b.count - a.count)
saveLangs(langs, true)
}
generateLanguages()