Skip to content

Instantly share code, notes, and snippets.

@kurokikaze
Created February 9, 2011 11:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurokikaze/4855324a5166a5dd87bb to your computer and use it in GitHub Desktop.
Save kurokikaze/4855324a5166a5dd87bb to your computer and use it in GitHub Desktop.
var express = require('express'),
redisServer = require('redis');
var ga = '<script type="text/javascript">\
var _gaq = _gaq || [];\
_gaq.push(["_setAccount", "UA-3286932-12"]);\
_gaq.push(["_trackPageview"]);\
(function() {\
var ga = document.createElement("script"); ga.type = "text/javascript"; ga.async = true;\
ga.src = ("https:" == document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js";\
var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ga, s);\
})();\
</script>';
var app = express.createServer();
app.get('/', function(req, res) {
res.header('Content-Type', 'text/html; charset=UTF-8');
res.send('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> \
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">\
<head>\
<title>Число Бумбурума</title>\
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\
' + ga + '\
</head>\
<body>\
<style>\
body, html {\
height: 100%;\
}\
body {\
margin: 50px 100px;\
background-color: white;\
}\
input[type=text] {\
font-size: 3em;\
width: 99%;\
font-family: verdana, sans-serif;\
padding: 1px 0px;\
-webkit-appearance: textfield;\
border: 2px inset;\
color: darkGray;\
}\
label {\
display: inline;\
margin-bottom: 2px;\
font: .75em Verdana, sans-serif;\
font-weight: bold;\
color: black;\
}\
h1 {\
margin: 50px 0 1em 0;\
font: 2.17em/100% Verdana,sans-serif;\
letter-spacing: -1px;\
color: #999;\
display:block;\
}\
div.wrapper {\
border: 1px solid white;\
margin-left: 249px;\
width: 50%;\
}\
p.about {\
margin-top: 40px;\
color: #999;\
}\
div.credits {\
position: fixed;\
bottom: 4px;\
font: 0.7em Verdana,sans-serif;\
color: #999\
}\
input[type=submit] {\
background: #D4D0C8 url("http://habrahabr.ru/i/form/loader_field.gif") no-repeat -1000px 0;\
color: #000;\
outline: none;\
margin: 15px 0 5px 0;\
font-family: verdana, sans-serif;\
font-size: 1.4em;\
}\
</style>\
<div class="wrapper">\
<h1>Число Бумбурума</h1>\
<form action="/number" method="GET">\
<label for="username">Имя пользователя:</label>\
<input type="text" name="username" value=""/>\
<div class="btn_holder"><input type="submit" value="Узнать"/></div>\
</form>\
<p class="about"><a href="/about">Что это такое?</a></p> \
<div class="credits">Февраль 2011, <a href="http://kuroikaze85.wordpress.com">Kuroki Kaze</a> и <a href="http://nodejs.ru">nodejs.ru</a>\
</div>\
</body>\
</html>');
});
app.get('/number', function(req,res) {
var username = req.query.username.replace('_', '-');
var redis = redisServer.createClient();
redis.sismember('newusers', username, function(err, ismember) {
if (ismember) {
redis.get('newusers:' + username + ':level', function(err, level) {
redis.get('newusers:' + username + ':path', function(err, path) {
redis.quit();
var pathpieces = path.split(' ');
var newpath = '';
for (var piece in pathpieces) {
if (pathpieces[piece]) {
newpath += '<a href="http://' + pathpieces[piece] + '.habrahabr.ru">' + pathpieces[piece] + '</a><span class="to">&gt;</span>';
}
}
newpath += '<a href="http://' + username + '.habrahabr.ru/">' + username + '</a>';
res.header('Content-Type', 'text/html; charset=UTF-8');
res.send('<html> \
<head><title>Число Бумбурума для ' + req.query.username + '</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' + ga + '</head>\
<body>\
<style>\
body, html {\
height: 100%;\
}\
body {\
margin: 50px 100px;\
background-color: white;\
}\
h1 {\
margin: 50px 0 1em 0;\
font: 2.17em/100% Verdana,sans-serif;\
letter-spacing: -1px;\
color: #999;\
display:block;\
}\
div.number {\
font: 4em Verdana,sans-serif;\
color: #D3E2F0;\
display: block;\
width: 99%;\
text-align: center;\
}\
div.path {\
width: 99%;\
text-align: center;\
margin-top: 30px;\
}\
div.path a {\
margin-right: 11px;\
color: #666;\
font: normal 92.4%/1.5em arial;\
padding-left: 18px;\
background: url("http://i.habrahabr.ru/i/bg-user2.gif");\
background-repeat: no-repeat;\
}\
div.path span {\
margin-right: 11px;\
font: normal 92.4%/1.5em arial; \
color: #333;\
}\
p.about {\
margin-top: 40px;\
color: #999;\
}\
div.credits {\
position: fixed;\
bottom: 4px;\
font: 0.7em Verdana,sans-serif;\
color: #999\
}\
</style>\
<div class="wrapper">\
<h1>Число Бумбурума для ' + req.query.username + ':</h1>\
<div class="number">' + level + '</div>\
<div class="path">\
' + newpath + ' \
</div>\
<p class="about"><a href="/about">Что это такое?</a></p>\
<div class="credits">Февраль 2011, <a href="http://kuroikaze85.wordpress.com">Kuroki Kaze</a> и <a href="http://nodejs.ru">nodejs.ru</a>\
</div>\
</body>\
</html>');
});
});
} else {
res.send('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> \
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">\
<head>\
<title>Число Бумбурума</title>\
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\
' + ga + '\
</head>\
<body>\
<style>\
body, html {\
height: 100%;\
}\
body {\
margin: 50px 100px;\
background-color: white;\
}\
h1 {\
margin: 50px 0 1em 0;\
font: 2.17em/100% Verdana,sans-serif;\
letter-spacing: -1px;\
color: #999;\
display:block;\
}\
div.wrapper {\
border: 1px solid white;\
margin-left: 249px;\
width: 50%;\
}\
p.about {\
margin-top: 40px;\
color: #999;\
}\
div.credits {\
position: fixed;\
bottom: 4px;\
font: 0.7em Verdana,sans-serif;\
color: #999\
}\
</style>\
<div class="wrapper">\
<h1>Число Бумбурума для ' + req.query.username + ' не определено</h1> \
<p>Этот пользователь не связан с Бумбурума цепью друзей. Такое бывает на Хабрахабре. А может быть такого пользователя не существует вовсе.</p>\
<p class="about"><a href="/about">Что это такое?</a></p> \
<div class="credits">Февраль 2011, <a href="http://kuroikaze85.wordpress.com">Kuroki Kaze</a> и <a href="http://nodejs.ru">nodejs.ru</a>\
</div>\
</body>\
</html>');
}
});
});
app.get('/about', function(req,res) {
res.send('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> \
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">\
<head>\
<title>Число Бумбурума</title>\
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\
</head>\
<body>\
<style>\
body, html {\
height: 100%;\
}\
body {\
margin: 50px 100px;\
background-color: white;\
}\
h1 {\
margin: 50px 0 1em 0;\
font: 2.17em/100% Verdana,sans-serif;\
letter-spacing: -1px;\
color: #999;\
display:block;\
}\
div.wrapper {\
border: 1px solid white;\
margin-left: 249px;\
width: 50%;\
}\
</style>\
<div class="wrapper">\
<h1>Что это вообще такое?</h1> \
<p>У математиков есть такая интересная вещь &mdash; <a href="http://ru.wikipedia.org/wiki/Число_Эрдёша">число Эрдёша</a>. Это расстояние от любого математика до Пола Эрдёша через совместно написанные работы. У самого Эрдёша оно равно нулю, у всех его соавторов &mdash; единице, у соавторов его соавторов &mdash; двойке, и так далее.</p>\
<p>Я решил сделать то же самое применительно к Хабрахабру &mdash; просчитать путь от какой нибудь отправной точки до каждого пользователя. В качестве отправной точки был выбран <a href="http://boomburum.habrahabr.ru">Boomburum</a>. В течении суток <a href="http://kuroikaze85.wordpress.com/2011/02/01/htmlparser-soupselect-crawler/">краулер</a>, написанный на node.js, собирал данные с Хабрахабра. Полученные данные складывались в Redis.</p>\
<p>В результате оказалось что из примерно 60 тысяч пользователей Хабра с Бумбурумом связаны чуть больше 25 тысяч. У большинства пользовалей число Бумбурума 3 либо 4. Самое большое зарегистрированное число Бумбурума &mdash; 10 (хабрадевушка <a href="http://festgo.habrahabr.ru">festgo</a>).</p>\
<p><em>А где <a href="http://twitter.com/shoohurt/status/33470450113712128">Шухарт</a>?</em></p>\
<p></p>\
</div>\
</body>\
</html>');
});
app.listen(80);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment