BaNru

Пикабушник
11К рейтинг 23 подписчика 12 подписок 57 постов 5 в горячем

Говнокодим кликербота на JS на примере Пикабу. Часть 2.

Первую часть приняли не особо доброжелательно. Л - логика Пикабу. Очень странная. Полезные посты, по субъективному мнению, сливают, а хрень всякую выводят в горячее. И только сейчас понял, наверное по этому я горячее уже давно не читаю. Ну ладно, хватит плакаться.


Специально для моих двух анонимных подписчиков, которые появились после предыдущей части.


Немного обдумав понял, что не стоит делать провокационные посты, поэтому в этом посте я покажу полезную фичу для людей интенсивно пишущих на Пикабу. А именно покажу, как сделать Уведомления о новых сообщениях и в ленте.


Всем местным известно, что в сайдбаре, в карточке профиля, при появление нового поста в ленте и/или сообщения появляется число сообщений. Вот на основе этого и сделаем себе маленький скрипт, в несколько строк. Подобный скрипт можно использовать на любом сайте, можно наблюдать за любым элементом, даже на коком-нибудь условном Форексе следить, когда цена упадёт или вырастет и вовремя среагировать.


В данном посте я буду использовать console.log(), это системная функция, которая позволяет выводить сообщение в консоль. Например console.log('Привет, мир!'); - выведет в консоль сообщение "Привет, мир!". Она очень удобна для отладки. Есть и другие виды сообщений в консоль console.*, но не будем он них, их использование очень редкое, просто знайте, что они есть и подробности знает гугл.


Ещё раз повторю, что писал в прошлый раз. Это не учебник. Скорее наоборот. Это просто способ заинтересовать и небольшие материалы как быстро сделать себе простенькие скрипты. Примеры позволяют быстрее втянуться и начать изучать. Мне всегда было интереснее разбирать готовые примеры, часто без описания, просто чужой код, а не читать тонны макулатуры. Интереснее было писать свои велосипеды, опираясь на чужой готовый код.



Глава 2. Условия


Немного теории об условию if/else. Это универсальное условие и есть оно во всех языках. Это много где уже описывалось, но я попробую объяснить на пальцах.


Алгоритм работы очень прост, на человекоподобном русском языке это выглядит так:

если (if) условие совпадает, то выполняем такой-то код

иначе (else) выполняем другой код


На синтаксисе JS это выглядит как-то так:

if (условие){ console.log("Условие верное"); }

else { console.log("Условие неверное") }


В условиях может быть что угодно, зависит от языка и его фич. Все разбирать я не буду, для пример лишь покажу часто используемые: равно == (===), не равно != (!==), больше >, меньше <, больше или равно >=, меньше или равно <=.


То есть например нам надо проверить A равна ли нулю

if (a === 0){ console.log("А равна нулю"); }

else { console.log("А не равна нулю"); }


Также часто используется ещё "промежуточное" условие if else, когда нам надо сделать больше.

if (a === 0){ console.log("А равна нулю"); }

if else (a > 0){ console.log("А больше нуля"); }

if else (a < 0){ console.log("А меньше нуля"); }

else { console.log("не одно из условий не совпало"); }


Данные условия будут выполняться по очереди, пока не найдётся удовлетворяющее условие или не закончатся условия. Если условие совпало, то проход по условиям прекращается, дальше оно не выполняется. То есть только одно условие срабатывает, первое попавшиеся.


Ещё один главный момент: можно использовать if без else. То есть вот такой код:

if (a === 0){ console.log("А равна нулю"); }

если будет совпадение, то он выполнится, если не будет, то соответственно оно просто не выполнится.


Если указано else, то в случае несовпадения else обязательно выполнится, но иногда нам этого не надо, но надо несколько условий, тогда можно сделать сделать вот такое условие:

if (a === 0){ console.log("А равна нулю"); }

if else (a > 0){ console.log("А больше нуля"); }

if else (a < 0){ console.log("А меньше нуля"); }

И в случае совпадения - условие выполнится, иначе ничего не произойдёт. Тут также проход будет пока не встретится совпадение, в противном случае всё проигнорируется.


Также нам надо знать, что любое условие проверяет на само сравнение, а результат сравнения. Если вы в консоли выполните 0 === 0, то увидите ответ true, если выполните 1 === 0, то выведет false. Это называется логическое значение (boolean) true/false или по нашему истина/ложь. Именно его проверяет условие. Также почти всё, что не равно true - будет приравниваться к false.


Гуру, которые осилили прочтение данного материала, усмехнуться и вспомнят про особенности (фичи) JS. Но в данном материале я не хотел бы затрагивать их. Кому интересно - с некоторыми особенностями могут ознакомиться по ссылке.


В предыдущем посте я описывал как находить необходимый нам элемент. По такому же принципу ищем наш элемент (цифру новых постов ленте или сообщений) и копируем его селектор. (Далее актуально для Firefox, Хром копирует более длинный уникальный селектор) Непосредственно сама цифра "скрывается" за селектором .b-user-menu-list__count, но, к сожалению, данный селектор выберет нам только первую цифру, а именно ленту, если там что-то будет. А если ленты не будет, то сообщение. А нам надо точно выбирать ленту и точно выбирать сообщения. Для этого нам надо найти родителя, это будет li с его уникальным селектором .b-user-menu-list > li:nth-child(6) и добавляем его в начале нашего селектора через пробел, получится вот такой селектор для сообщений .b-user-menu-list > li:nth-child(6) .b-user-menu-list__count. Точно также находим создаем селектор для ленты .b-user-menu-list > li:nth-child(4) .b-user-menu-list__count


Наличие элемента нам и надо проверить через условие. Если выполнить в консоли выбор нашего элемента, через querySelector (подробнее я описывал в предыдущем материале) document.querySelector('.b-user-menu-list > li:nth-child(6) .b-user-menu-list__count'), то увидим его, либо null. Таким образом мы можем сделать наше первое простое условие:

if(document.querySelector('.b-user-menu-list > li:nth-child(6) .b-user-menu-list__count') !== null){

console.log("У нас есть новые сообщения!");

}

Точно также поступаем с лентой:

if(document.querySelector('.b-user-menu-list > li:nth-child(4) .b-user-menu-list__count') !== null){

console.log("У нас есть новинки в ленте!");

}


Теперь после запуска этих строк у нас в консоли будет появляться надпись, если есть новые сообщения.



Глава 3. Уведомления (Notification).


Мануал по Notification


Надпись в консоль нас не уведомит, поэтому будем использовать уведомления Notification. Я не буду вдаваться в подробности проверки включены или выключены уведомления, чтобы код у нас не разрастался и не мешался. Будем считать, что вы сами разрешили уведомления на странице:

- В Firefox: правой кнопкой мыши на странице —> Информация о странице —> Разрешения —> Отображать уведомления —> Разрешить.

- В Chrome: правой кнопкой мыши на странице —> Посмотреть сведения о странице —> Оповещения —> Всегда разрешать на этом сайте.

- В Opera Next: Settings —> Preferences —> Advanced —> Notifications


Само уведомление отправить очень просто, выполните вот этот кода в консоли:

new Notification("У нас есть новые сообщения", {

body : "Я не шучу",

icon : "http://cs.pikabu.ru/images/big_size_comm/2013-01_6/13593679594707.png"

});


Указываем заголовок сообщения, текст сообщения и иконку. Думаю всё ясно. Теперь соединим получившийся код


if(document.querySelector('.b-user-menu-list > li:nth-child(6) .b-user-menu-list__count') !== null){

new Notification("У нас есть новые сообщения", {

body : "Я не шучу",

icon : "http://cs.pikabu.ru/images/big_size_comm/2013-01_6/13593679594707.png"

});

}

if(document.querySelector('.b-user-menu-list > li:nth-child(4) .b-user-menu-list__count') !== null){

new Notification("У нас есть новинки в ленте", {

body : "Я не шучу",

icon : "http://cs.pikabu.ru/images/big_size_comm/2013-01_6/13593679594707.png"

});

}



Глава 4. UserScripts.

И опять у нас ничего интересного. Нам же не интересно руками запускать код. Верно? Для этого и придумали UserScripts. В Хроме можно поступить по простому: создать JS файл и забросить его в расширения, при этом заполнив верно заголовки. Но это не очень удобно, поэтому рекомендую, независимо от браузера поставить GreaseMonkey или TamperMonkey. Затем в GM или TM создать новый скрипт. Думаю объяснять подробностей не надо, разберетесь как. И там в настройках (в GM это "включения", а в TM - это match) добавить какую-нибудь небольшую и нейтральную страницу, например http://pikabu.ru/html.php?id=faq. Добавляйте в скрипт код, который ранее сделали, сохраняйте и переходите на страницу FAQ. Если у вас есть новые сообщения, то у вас выскочить уведомление.



Глава 5. Таймеры


И опять у нас ничего интересного. В JS есть два типа таймеров setTimeout и setInterval. Отличия между ними небольшие: первый выполняет заданные ему код только один раз через заданное время, а второй код бесконечно, пока не остановить, тоже через заданное время. В данном скрипте мы будем пользоваться только setTimeout.


При заходе на страницу у нас теперь работает уведомление. Но если мы зайдём на страницу, то мы и сами увидим. Поэтому надо сделать, чтобы скрипт сам проверял наличие. Можно сделать ajax и даже плагин, чтобы фоном всё это работало. Но это в других статьях. А сейчас, чтобы завершить повествование сделаем просто обновление страницы по таймеру. Тут всё достаточно просто, возьмем любой код и обернем его в интервал. Так например из примера по ссылке: setTimeout(function() { alert('Привет') }, 1000);


Чтобы обновить страницу надо выполнить простую функцию location.reload(); Почему её? Потому что гугл выдаёт её первой по запросу "javascript page reload" :D


В примере время установлено в 1000 мс, это 1 секунда, это слишком быстро. Нам же достаточно будет раз в 3 минуты. 3 минуты * 60 секунд и на 1000 мс = 180 000. Код получается следующий:

setTimeout(function() {  location.reload(); }, 180000);


Добавляем его в конец нашего скрипта. Сохраняем и переходим на страницу FAQ. Теперь пока у нас открыта эта страница - скрипт будет следить за новыми сообщениями и если они появятся - сообщит нам, а мы можем не спеша читать ленту на другой вкладке или сидеть во Вконтактике, или искать новую картинку, чтобы запостить на Пикабу.


(Слева Firefox и GM, Справа Хром и TM)

Говнокодим кликербота на JS на примере Пикабу. Часть 2. Javascript, Быдлокодинг, Длиннопост

Всё не так страшно, как казалось.


На этом всё.


Если вдруг в этот раз не сольют пост, то в следующий раз, возможно, напишу материал о том, как сделать свой маленький плагин (чтобы вкладку не держать открытой) и расскажу об ajax (xhr).

Показать полностью 1

Очередь в паспортном

Навеяно навеянным постом http://pikabu.ru/story/ozhidanie__svoloch_4641866 и комментариями.


Давно, когда менял паспорт (в 20 лет вроде), как все "нормальные" люди поперся в паспортный, с утра пораньше, к открытию. Там очередь стояла от входа до угла здания. Больше 100 человек точно, на здание с десятком кабинетов/окон. И, как потом выяснилось, многие приходили и занимали очередь часов в 6 утра. Записывались на листочек. Очень много конечно же было приезжих. Были и "продвинутые", которые занимали, как на работу (начинающие всякие дельцы, у кого ещё нет связей, типа риэлторов или оформителей социалки). Простоял пару часов, очередь почти не сдвинулась, приближался обед. Понял, что ловить нечего и ушел.

Очередь в паспортном Очередь, Паспортный стол

Через какое-то время я пошел в паспортный примерно за час до закрытия. В окна, в которые стояла основное число людей (если не ошибаюсь для гостей) - стояло всего человек 5-10. Ещё столько же стояло в дальние кабинеты (не знаю что там). В окно, которое мне надо было (подача документов и выдача) стояло всего 3-4 человека. Очередь прошла минут за 5-10. Не помню почему, но в тот день мне пришлось бежать фотографироваться, то ли неверный формат был фото, то ли потому что надо было временный паспорт, а на него не хватило фоток. В итоге я успел сбегать на соседнюю улицу сфотографироваться и где-то за 10-15 минут до закрытия принес фотографии. Народу вообще не было, сразу подошел к пустому окну.


Получал также, во второй половине дня, народу было очень мало, правда подождать пришлось минут 20-30, но даже стульчики были свободные.


Подобное несколько раз наблюдал в рег.палате и даже в больницах. Подобное случалось не только со мной, где-то на просторах интернета я видел подобные сообщения. Очереди появляются по нескольким причинам (не только в паспортном):

- бабульки, в паспортном это меньшее из зол;

- многие хотят до обеда почему-то, может потому что ещё куда-то надо бежать оформляться;

- главное зло "свои люди", специалисты с утра обрабатывают своих людей и неспешно принимают остальных, поэтому очередь почти не двигается;

- традиция с утра бежать, все же бегут с утра и стоят и мне надо постоять;

- другая неведомая сила.


В общем своего рода лайфхак: если с утра большая очередь, попробуйте прийти часов в 15-16, почти всегда будет свободно. Но попытайтесь попасть до 17, если заведение работает, например, до 19, потому что там уже очередь набирается из тех, кто идёт с работы.


PS Сейчас же, конечно, лучше делать всё через сайт ГосУслуги. Быстрее и никаких очередей.

Показать полностью 1
6

Говнокодим кликербота на JS на примере Пикабу. 1: click() и querySelector()

Введение


Давно думаю попробовать написать несколько материалов, как легко в браузере писать ботов и не только. Не кармы ради, а плюсиков для. Шутка с долей шутки.


Данный материал не является пособием по программированию. И данный код ни в коем случае не считать эталонным! Использовать его надо с умом в любых интересах в познавательных целях, не во зло.


Если материал окажется интересным, то продолжу.


В материале могут встречаться разного рода ошибки и опечатки, ибо это пишется с ходу, а исправить их Пикабу не позволит. Не сердитесь сильно.


Пока писал пост, гадал: "забанит, не забанит, забанит, не забанит ли меня администрация за такой пост?"


А к гуру JS просьба править меня, но не мешать. Знаю, сейчас набежит куча умных и напишут  готовые куски года с готовые кликерами, тем самым испортив дальнейший накал страстей в постах. В общем набегут профи из отряда спойлеристов. Но, уважаемые гуру, прежде чем писать, вспомните про одного такого на премьере Звездных войн :D



Глава 0. Немного обо всём этом


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


По сути эти боты - это просто кликеры (автокликеры), хотя можно сделать и не кликера, а фонового, но это, если и буду описывать, то в самом конце цикла статей.


Также, для удобства работы рекомендую пока что ознакомиться, а в будущем обязательно поставить Greasemonkey или Tampermonkey. Есть ещё Scriptish, но он мне не понравился. А также можно использовать UserScripts "как есть" в Хроме, но это чуть менее удобно.


Тут и далее материал будет писаться на основе браузера Firefox, ибо там есть очень хороший плагин для разработчиков FireBug и я к нему привык. Но в других браузерах есть всё тоже самое, свои инструменты для разработчика, просто чуть по другому выглядит и называется. Чтобы продолжить их надо открыть, для этого надо нажать F12. Если у вас не открываются они, например в Сафари, то ищем в гугле "название_вашего_браузеран открыть инструменты разработчика".


Далее под Хромом будут подразумеваться все браузеры основанные на хромоподобном движке webkit/blink, это Опера, Яндекс и другие.


Все названия элементов меню и прочего я буду писать примерные, обобщенные, а вы уже ищите что-то похожее.


Скрины, если и будут, то могут быть из разных браузеров, там где это нагляднее показывается.


Данный материал не рассказывает о кроссбраузерности. В материале используются только современные достижения для современных браузеров.



Глава 1. Функция click() и querySelector


В данной главе мы научимся пользоваться консолью, научимся искать и изменять элементы, ну и кликать.


Мануал

click() https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement...

querySelector() https://developer.mozilla.org/ru/docs/Web/API/Document/query...


Начнем с авторизации на Пикабу. Все свои эксперименты с авторизацией я провожу в Инкогнито режиме на тестовом аккаунте, но это не принципиально.


И так мы открыли Инструменты разработчика и там находим Консоль. В ней мы будем тестировать наш JS код.


Авторизация происходит следующим образом: вводится "логин" и "пароль" и нажимается кнопка "войти". Первым делом нам надо ввести данные. Но надо знать куда ввести, в какой элемент на странице, то есть найти элементы под названием input. Конечно же не любые, а именно для логина и пароля. Кто пользуется Firebug или Хром необходимо будет поставить курсор на этот input, нажать правую мышь и выбрать пункт "инспектировать элемент". В консоли откроется наш элемент. Если у вас нет подобного пункта, то в консоли должна быть кнопочка придется искать его по всему документу самим.

(на картинке ниже слева Хром, правее Firebug)

Говнокодим кликербота на JS на примере Пикабу. 1: click() и querySelector() Javascript, Нелегально, Быдлокодинг, Длиннопост

После того как выбрали его, необходимо найти пункт типа "скопировать селектор" или CSS. Вроде любой браузер должен копировать самый короткий селектор. Кроме Firebug, он копирует самый длинный, полный селектор.


Для input'а логина у меня получился вот такой "#username", то есть выбор по ID. Для пароля получилось аналогично "#password". Ну и чтобы потом не возвращаться, скопируем кнопку "button.b-button:nth-child(2)", тут уже нет ID, поэтому селектор получается сложнее.


Более подробно с этим можно ознакомиться по ссылке выше или в учебнике по CSS, это основы CSS.

Кратко

https://learn.javascript.ru/css-selectors

Подробно

http://htmlbook.ru/metki/selektory


Теперь с помощью querySelector() мы может обращаться непосредственно к данным элементам. Наберем это в консоли, не забыв добавить document перед нашей функцией. Подробно вдаваться не буду, если кратко "Надо, Федя, надо", чуть подробнее вот тут http://javascript.ru/document, а более развернуто полно материала в гугле.


Получается вот такие строки:

document.querySelector('#username');

document.querySelector('#password');

document.querySelector('button.b-button:nth-child(2)');


Выполняя каждую строку отдельно, в консоли мы увидим наши элементы.

Говнокодим кликербота на JS на примере Пикабу. 1: click() и querySelector() Javascript, Нелегально, Быдлокодинг, Длиннопост

Чтобы вбить данные в форму нам надо заполнить атрибут value (http://htmlbook.ru/html/input/value). Достучаться до него очень просто: document.querySelector('#username').value;

Так просто не с каждым атрибутом, но сейчас не об этом.


Если мы попробуем выполнить данную строку в консоли, то мы получим то, что там вбито. По умолчанию у нас сейчас пустая строка. Чтобы заполнить, нам надо просто присвоить этому атрибуту значение: document.querySelector('#username').value = "Гость";

Обязательно брать строки в кавычки всегда!


Тоже самое нам надо повторить с паролем: document.querySelector('#password').value = "Пароль";


Выполняем эти строки в консоли и увидим, что форма заполнилась. Теперь нам надо её просто отправить, нажав соответствующую кнопку. В этом нам поможет функция click().

document.querySelector('button.b-button:nth-child(2)').click();


Выполняем эту строчку и у нас произойдёт отправка. Если выполнить все три строчки разом, то произойдёт сразу, в порядке переданных строк, заполнение и вход.


На этом авторизация (вход) готов, всего три строчки кода. В следующей статье на примере кликера будет цикл, чтобы заинтересовать и уже видеть результат.


"Бонусом": тоже самое можно сделать с выставлением плюса или минуса комментарию. Выбираем наш элемент и кликаем:

document.querySelector('#comment_ТУТЦИФРЫТЕКУЩЕГОКОММЕНТА > div:nth-child(1) > div:nth-child(1) > ul:nth-child(2) > li:nth-child(1) > i:nth-child(1)').click();

Говнокодим кликербота на JS на примере Пикабу. 1: click() и querySelector() Javascript, Нелегально, Быдлокодинг, Длиннопост
На этом всё. Хотел написать кратко, думал уложусь в несколько абзацев, а получилось как всегда, Остапа было уже не остановить.



Эпилог поста


В планах примерно такой порядок материал:

2. Цикл (какой-то один или два, а не все).

3. Условия (if/else) и Интервалы (setTimeout/setInterval)

4. Массив, хранилища (наверное только localStorage) и прочее что понадобится. например JSON.

5. Load (по сути пересказ материала https://learn.javascript.ru/onload-ondomcontentloaded)


Планы неточные, могут меняться, в частности по пожеланиям в комментариях.

Показать полностью 3
4

Video Blocker

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


Знаете какая красота теперь у меня в тренде? Всего десяток видео и нет ни каких тупых деток и свинок, а также почти все лайфхаки и топы выпилились. Уже почти 500 штук в черном списке. Если когда-нибудь автор ещё и общую базу по типу АдБлока сделает, то это будет вообще красота.


В рекомендованных тоже относительно чисто. Ради эксперимента я пробовал "скрывать" потому что "не понравилось" и "не интересен этот канал". Но не помогало. Всё равно вылазило или повторно, особенно если эта херня из тренда или другие видео с того канала всё равно лезли.


В итоге заблокировав полностью канал - избавляюсь от той хрени навсегда.


По моим наблюдениям про данный плагин Video Blocker мало кто знает. Это, своего рода, АдБлок для видео на Ютуб. Рекомендую!


Пост можно считать добровольной рекламой АдБлока и ВидеоБлокера :)

Показать полностью
9

Скоростной поезд

Очередная передача из цикла Непростые вещи, канала Наука 2.0


В фильме показана работа скоростного поезда “Velaro RUS” («Сапсан») в России и процесс его производства в Германии.


ЭВС «Сапсан» (Velaro RUS) - высокоскоростные электропоезда из семейства электропоездов Velaro производства компании Siemens, приобретённые ОАО "РЖД" для эксплуатации на российских скоростных железных дорогах.


Сапсан имеет ряд конструкционных отличий: воздухозаборники вынесены на крышу, поезда способны работать при температуре воздуха до минус 50 градусов, а их салон шире стандартного европейского почти на 30 см. Максимальная конструкционная скорость поезда составляет 300 км/ч, по российским дорогам скорость поезда ограничена 250 км/ч. Поезд использует рекуперативное торможение, что позволяет уменьшить затраты на электроэнергию.

Специально для детей

Специально для детей IVI, Дети, Реклама

Несколько лет назад (скрин из личного архива) удачно отключил AdBlock

2

Новые старые условия у Мегафона

Недавно пришла СМСка о том, что тариф изменился. Решил почитать.


В случае неиспользования услуг связи более 45 календарных дней подряд, начисляется абонентская плата в размере 450 руб. в месяц. Абонентская плата начисляется ежедневно, равными долями, до момента достижения порога отключения. Абонент в одностороннем порядке отказывается от исполнения Договора об оказании услуг связи путем неиспользования Услуг более 90 календарных дней подряд при условии нахождения баланса лицевого счёта равным порогу отключения либо ниже порога

отключения.

Данные условия на "Переходи на ноль", в других тарифах возможно подобное


Из-за этой херни я выкинул симку МТС, которой пользовался много лет. Теперь и Мегафон, но более драконовские цены.


На МТС было именно "неиспользование платных услуг", так мне оператор сказал. В описание тарифа написано, что просто "неиспользования услуг связи", но судя по посту похожему, созданному год назад http://pikabu.ru/story/zhlobyi_iz_megafon_nanosyat_otvetnyiy... многих могут ожидать сюрпризы.


Так что баяню и напоминаю. Рекомендую ознакомиться с изменениями тарифов megafon.ru/ad/newpf_0709

Показать полностью
0

На волне: мои рабочие места

В начале нулевых я работал вот тут

На волне: мои рабочие места Теги никто не читает, Работа, Врун, Длиннопост

Потом мне надоело и я сменил вид деятельности

На волне: мои рабочие места Теги никто не читает, Работа, Врун, Длиннопост

Текущее место работы

На волне: мои рабочие места Теги никто не читает, Работа, Врун, Длиннопост

И вы меня конечно же узнали

На волне: мои рабочие места Теги никто не читает, Работа, Врун, Длиннопост
Показать полностью 3
Отличная работа, все прочитано!