Pull to refresh

Comments 56

проблема была в знаке минус, который почему-то шел закодированно как-то

Вместо минусов перед рейтингом стоит Unicode Character 'EN DASH' (U+2013)
Спасибо, намотал на ус.
извините, вырвалось
Демо: habrastats.m.tom.ru
Мой дорогой сервер, давай, до свидания. Возможно, злобный хабраэффект тебя не победит.
Зря, скрипт дырявый в плане безопасности, только для локалхоста. Не проверяется даже, является ли id топика вообще числом.
Я проверял версию, которую загрузил Anonym — как минимум XSS в чистом виде там есть, попробуйте ввести в качестве id <script>alert(1)</script>
1487<script>alert(1)</script>95

Вот так, если точнее
Попробовал. Ничего не произошло. Что я делаю не так?
Странно, я проверял на вашем сервере — выскакивал alert и в коде содержался введенный id без фильтрации. Вы точно ничего не меняли? :-)
Пробовал без изменений. В хроме алерта не было.
Сейчас на всякий случай добавил еще проверку, чтобы наверняка.
Хром хитрый — у него защита от XSS атак есть. Надо смотреть исходный код или в других браузерах.
$id = intval(abs($id));
$dom->loadHTML(file_get_contents(sprintf('http://habrahabr.ru/post/%d/', $id)));

При беглом просмотре кода не нашел ничего подозрительного.
Логичнее делать abs ПОСЛЕ приведения к intval ;)
Вот тут я два раза, это нормально?)
Два раза в топе по плюсам (4 и 5)
Это вопрос не ко мне, а к автору.
Уважаемый Miraage, это нормально?
Да-да, исправился ниже :)
Извините, вопрос не вам)
Разные комменты с одинаковым автором.
Записал в TODO.
Спасибо.
Ага, ясно. Спасибо)
У вас плохое условие на проверку кеша, заново запускает сбор для таких значений:
— 148795''
— 148795'''
— 148795''''
— 148795'''''

Если набросать маленький скрипт, то возможно и без хаброэффекта можно ваш сервер положить.
Я особо не надеялся, что он вообще выживет.
Сейчас кэшируется всё как есть
proxy_cache_valid 200 301 302 304 20m; proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
Так как URL для 148795'' и 148795''' разный, то и кэшируются они независимо.
Не подскажете, как сделать правильно?
На backend делайте примерно так…
if(...ID имеет лишние символы)
{
    header('location: ссылка с нормальным ID');
    exit(0);
}
Лучше конечно бы средствами nginx это сделать, но пока сделал как вы написали.
Насколько я знаю, nginx так не умеет.
Вы шутите, сударь? Даже без привлечения встроенного Perl или Lua:

map $arg_id  $id_digits {
    "~(\d+)" $1;
}

if ($arg_id ~ "[^\d]") {
    return 302 http://example.com/app?id=$id_digits;
}

А я использовал JS. Писать на чём-либо вне браузера мне сразу расхотелось, ибо нужен приличный парсер, а в браузере уже всё готово — есть DOM (да ещё и jQuery на хабре используется).

Поэтому по-быстрому был написан скрипт, генерирующий статистику.
При желании это можно оформить в виде какого-нибудь букмарклета, только основательно подпилив — производительностью скрипт не блещет, так что его следует либо оптимизировать, либо модифицировать так, чтобы он не блокировал JS поток (Вряд ли тут помогут воркеры, т.к. вся нагрузка, на мой взгляд, идёт из взаимодействия с DOM, так что первый вариант, пожалуй, перспективнее).
Вы мне подали замечательную идею.
Надо будет написать userscript.
Я вообще забыл про их существование.
Кстати, меня давно просили сделать какой-нибудь рейтинг комментариев для любой статьи на Хабре (в рамках юзерскрипта HabAjax) — habrajax.reformal.ru/proj/?ia=261505, но никаких конкретных предложений дизайна не было.

То, что вы придумываете сейчас — это, практически, тоже рейтинг комментариев 1-го уровня. Если придумается что-то, годящееся вообще как полезный инструмент, можно выполнить в виде плагина к HabrAjax. Если будет полезно вообще для ориентировки в комментариях, можно встроить в скрипт.
И забыл добавить, что вариант с использованием jQuery из страниц Хабра в Хроме работать не будет, если делать так, как сделано у barmaley_exe. У меня оно без jQuery, что не сильно утяжеляет, т.к. есть .querySelector().
Я вообще не очень то и люблю js фреймворки.
Выпилить оттуда jQuery не составит никакого труда. Я использовал его лишь потому, что писать document.querySelectorAll, а потом делать из коллекции массив слишком утомительно.
Хм,
dSA = function(q){return [].slice.call(document.querySelectorAll(q) );}

Ну, и для проверки, вставил в HabrAjax такую штуку:

tA = dSA('.post .title');
'test'.wcl(tA , tA.length );

Выводит настоящий массив заголовков аннотаций (если страница — Лента, Избранное или прочий список) и его длину.
dSA = function(q){return [].slice.call(document.querySelectorAll(q) );}
Аж на 71 символ длиннее, чем если использовать jQuery :-)

А ещё это не освобождает от необходимости конвертирования childNodes в массив тем же образом (хотя, быть может, хватило бы node.querySelector('>div.message'), но это тоже длинно, да и требует проверки)

P.S. Лучше тогда уж как-то так
dSA = function(q, c){return [].slice.call(document.querySelectorAll.call(c || document, q) );}
Что длиннее уже на 94 символа :-)
dSA = function(q, c){return [].slice.call((c||document).querySelectorAll.call(q) );}


childNodes не очень хорошо, т.к. захватывает все текстовые ноды, их фильтровать потом… В общем, это решается такими мелкими функциями и получается микрооболочка. Наверное, именно так делают Zepto и прочие легковесные специализированные либы, лучше подходящие под скрипты без IE, чем jQuery.
Вы вызываете querySelectorAll с q в качестве this.
Вот поэтому лучше переиспользовать уже существующий код — меньше кода = меньше ошибок.
Вы вызываете querySelectorAll с q в качестве this.
Да, чтобы вернуть его как массив. А что в этом особенного?

Вот поэтому лучше переиспользовать уже существующий код
Подразумевается jQuery?
Это зависит от степени понимания того, что вы делаете своим кодом. Хочется 100 раз проверенный селектор jQuery — ваше право, только вы знаете, что приведёт к цели быстрее. Но вообще, мнение, что мощная библиотека с большей вероятностью избавит от ошибок, не совсем верно. Чем мощнее библиотека, тем больше в ней ошибок. А JS — всегда более проверенный язык, чем некоторая библиотека на нём, и ошибки с версиями браузеров появляются реже, и на тех же библиотеках сказываются.
Использовать jQuery только потому, что его использование «Аж на 71 символ короче»… Это как-то оооочень странно :)
Как по мне, так изобретать свой велосипед, когда доступа заботливо подключенная разработчиками Хабра мощная библиотека — вот что странно.
Впрочем, ежели Вам так нравится велосипедостроение с последующих хождением по граблям…
Ну, querySelectorAll — это не велосипед и не грабли. К тому же, если оформлять js-based решение как юзерскрипт или экстеншн, то нужно будет подключать фреймворк отдельно.
— querySelectorAll'у требуется обвязка в виде конвертации результатов из коллекции в массив.
— Для выбора прямых наследников узла по селектору нужно либо итерировать childNodes (возможно, избавляясь от текстовых узлов), либо как-то извращаться с querySelectorAll (как именно — не очевидно на первый взгляд).
— node.querySelectorAll — слишком длинно (да, в консоли есть автокомплит, но он не всегда работает).

На стадии прототипирования Когда всё, что требуется — несколько строк разметки статистики о топике, важно быстро получить рабочее решение, а не тратить сотни человекочасов, планируя и реализуя гибкую и масштабируемую архитектуру.

P.S. Все рассуждения были проведены в рамках моего решения.
P.P.S. Резюмируя всё вышесказанное, напомню ещё раз (или проясню, если это не очевидно), что инструменты я выбирал, стараясь максимизировать скорость написания скрипта. Ни о какой мнимой задаче последующей доработки скрипта речи, разумеется, не было.
Так дополните ваше решение более юзабельной оболочкой — оберните его в юзерскрипт (принципы есть в статье), да добавьте хотя бы кнопку на странице, которая будет пересчитывать значения и писать их в алерт
Сомневаюсь, что это кому-либо нужно.
Очевидно, инициатору хабрафуршета это нужно.

Вы же не поленились написать скриптец, так почему бы ему не приделать простейший UI? Всё же написать юзерскрипт проще и быстрее, чем экстеншен, зато устанавливается он практически так же.

К тому же, этот скилл может вам пригодиться для разработки аналогичных «микроинструментов многоразового использования»
Написано же «Decodes any %## encoding in the given string. Plus symbols ('+') are decoded to a space character.»
А вот комментарии из ссылки я на заметочку возьму. Спасибо :)
А вот это мне совсем непонятно. Для 1М поста отображает, для 100001 тоже. Странный какой-то баг.
В логах что пишет?
[Fri Aug 03 15:45:39 2012] [error] [client 91.221.x.x] PHP Fatal error:  Call to a member function getAttribute() on a non-object in /.../habraparser.php on line 107, referer: http://habrahabr.ru/post/148939/
[Fri Aug 03 15:45:39 2012] [error] [client 91.221.x.x] PHP Stack trace:, referer: http://habrahabr.ru/post/148939/
[Fri Aug 03 15:45:39 2012] [error] [client 91.221.x.x] PHP   1. {main}() /.../habrastats.php:0, referer: http://habrahabr.ru/post/148939/
[Fri Aug 03 15:45:39 2012] [error] [client 91.221.x.x] PHP   2. Habraparser->getOutput() /.../habrastats.php:19, referer: http://habrahabr.ru/post/148939/
[Fri Aug 03 15:45:39 2012] [error] [client 91.221.x.x] PHP   3. Habraparser->topQuestions() /.../habraparser.php:64, referer: http://habrahabr.ru/post/148939/
Sign up to leave a comment.

Articles