?

Log in

Previous 10 | Next 10

Nov. 28th, 2008

DMakeev

dmakeev

Удалить вирусы с сайта

Ситуация:
- есть сайт, зараженный вирусом-трояном. Т.е. в HTML-код вписаны "чужеродные" iframe. Сайт большой, руками удалять долго и нудно. Решение нужно автоматизировать.

Задача:
- обход сайта и удаление из .php, .htm и .html-файлов заданных кусков HTML

Порядок действий:
1. Бэкапим сайт.
2. Сохраняем скрипт в корень сайта (или куда удобно, но не забываем прописать пути - см. ниже)
2. Указываем свой IP
3. В массив viruses добавляем свои iframe, которые нужно удалять
4. Если скрипт размещен не в корне сайта, указываем стартовую папку. Вторым параметром функции start указываем 0 - чтобы сначала проверить что находит
5. Запускаем. Получаем список файлов, в котором обнаружены бяки.
6. Если все норм, указываем в вызове start вторым параметром 1. Запускаем.
7. На всякий случай проверяем все ли нормально с сайтом.
8. Идем пить кофе.

Что стоило бы сделать, но руки не дошли:
1. Вынести список проверяемых типов файлов в конфиг
2. Сделать список путей, которые нужно прокидывать
3. Прикрутить междумордие
UPD:
4. Возможность задавать ифрейм регуляркой

ИсходникCollapse )

Nov. 25th, 2008

wolverene

stekar

селектор падежа...

В одну строку...

$cnt.(substr($cnt, -1)>0 && substr($cnt, -1)<5 && !(strlen($cnt)>1 && substr($cnt, -2, 1)==1) ? (substr($cnt, -1)==1 ? ' рубль' : ' рубля') : ' рублей')


Разворачиваем в читабельный вид...Collapse )
Tags: ,

Oct. 23rd, 2008

DMakeev

dmakeev

Бэкапим сайт

Задача: сделать автоматическое бэкапирование сайта (сайтов). Задание должно запускаться по cron`у, архивировать БД и файлы сайта. При этом желательно иметь возможность настроить параллельно несколько заданий - к примеру, ежедневные и еженедельные дампы.

В cron с заданной периодичностью ставим вот такой простенький скрипт:

#!/bin/bash
# Путь к корневой папке проекта - для удобства
dir_base="..."
# Путь к папке с бэкапами
dir_backup=$dir_base"/backup"
# Путь к архивируемой папке
dir_site=$dir_base"/httpdocs"
# Пользователь БД
db_user="..."
# Пароль БД
db_pass="..."
# Название БД
db_name="..."
# Название бэкапа - daily, weekly и т.д - чтобы можно было отличать один бэкап от другого
backup_name="daily"

# Бэкапим базу данных
mysqldump -u $db_user --password=$db_pass $db_name > $dir_site/backup_$backup_name.sql
# Копируем старый дамп - чтобы если во время архивирования что-то гакнется, осталась старая версия
cp dir_backup/backup_$backup_name.tgz dir_backup/backup_$backup_name.old.tgz
# Собираем файлы в tar и попутно архивируем
tar -czf $dir_backup/backup_$backup_name.tgz $dir_site
# удаляем дамп БД - он больше не нужен
rm $dir_site/backup_$backup_name.sql
# Удаляем старую версию.
rm dir_backup/backup_$backup_name.old.tgz

exit 0


Что еще можно сделать:
- отправлять письмо после завершения. А на удаленной машине ловить это письмо и выкачивать бэкап.

UPD: Добавил копирование старого дампа и сжатие при сборке tar
DMakeev

dmakeev

Отслеживание нагрузки *nix-сервера

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

Простое решение, написанное на коленке:
// Получаем загрузку
exec('top |grep "load average" 2>&1', $topOutput);
// Утилита top возвращает строку вида:
// top - 00:39:25 up 6 days,  8:28,  1 user,  load average: 0.00, 0.03, 0.08
// при этом последние три числа - среднее количество процессов, ожидающих выполнения
// за последние 5, 10 и 15 секунд. Нормальным является значение до 10, хотя, конечно же
// вариации возможны - лучше подбирать под конкретную ситуацию.
// Выкусываем значения
if(preg_match('!\s(\d{1,3}\.\d{2}),\s+(\d{1,3}\.\d{2}),\s+(\d{1,3}\.\d{2})\s!s', $topOutput[0], $topMatch)) {
    // Проверяем два значения - загрузку "сейчас" и "давно". По первой мы проверяем 
    // насколько велика загрузка в текущий момент времени, по второй - что просиходит
    // с машиной вообще. В принципе можно ограничиться только первым значением
    if((float)$topMatch[1] > 10 || (float)$topMatch[3] > 10) {
        // Если нагрузка превышает заданный предел - завершаем работу
        exit;
    }
}

К недостаткам решения стоит отнести вызов exec - не работает в safe mode.
К преимуществам - эффективность и универсальность.
Куда стоит двигать:
- мне не нравится вызов top, думаю, это можно сделать через что-то менее масштабное
- по хорошему нужно хранить статистику аварийных завершений - грубо говоря если последние 10 запусков задачи не удались, задача выполняется несмотря на нагрузку (или планка нагрузки поднимается, чтобы совсем уж машину в штопор не пустить)

Nov. 28th, 2007

DMakeev

dmakeev

Ajax-переходы и кнопка Back

Задача в двух словах: нужно фиксировать события, выполняемые JavaScript`ом, в истории браузера.

Исходные данные: есть сайт, переходы между страницами реализованы ajax`ом.

Задача:
а. Заставить кнопки Back и Forward (и все остальное что связано с history бразузера) работать как подобает.
б. Пользователи должны иметь ссылку на ТЕКУЩУЮ страницу, в не зависимости от того, сколько переходов было совершено. Если пользватель зашел на страницу А и перешел на странцу Б, он должен иметь ссылку на страницу Б, причем с минимальным включением мозга.


РешениеCollapse )

Где внедрено: evraz.com

Oct. 26th, 2007

DMakeev

dmakeev

Сквозная авторизация на нескольких сатах

Задача: Пользователь авторизуется на сайте А. Нужно авторизовать его также на сайтах Б и С. Сайты располагаются на разных доменах.

Порядок работы:

  • При авторизации (или любом ином действии, требующем авторизации на удаленных сайтах), для каждого удаленного сайта выполняем следующее:
    Создаем IFRAME, загружаем в него url myloginform.php?site_id=111

    • В файле /myloginform1.php:
    • формируем HTML формы, соответствующей форме авторизации на удаленном сайте (сайт вычисляем по $_GET['id']).
    • берем данные текущего пользователя и подставляем в поля формы.
    • при загрузке страницы яваскриптом жмем сабмит.

  • Удаляем IFRAME

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

Sep. 18th, 2007

DMakeev

dmakeev

Проект, управляемый заказчиком

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

Есть правило - заказчик должен быть доволен. Мало осталось компаний, которые думают иначе. Но зачастую за "заказчик должен быть доволен здесь и сейчас" забывается "заказчик должен быть доволен в итоге". Стремясь сделать заказчика довольным "сейчас", менеджмент исполнителя зачастую идет на поводу у заказчика. При этом теряется одно из главных условий успешности проекта - прогнозируемость, - ход проекта более не зависит от исполнителя. Никто уже не может сказать что будет происходить с проктом завтра и через неделю.
Результат - сорванные сроки, трещащий по швам бюджет, львиная часть работ делается на финальной стадии в формате "горит". Исполнителю проект поперек горла, заказчик не доволен, продукт получился хуже, чем мог бы быть.

Резюмируем: заказчик может быть облизан с ног до головы, но он никогда не должен управлять процессом.
Мысль простая как три таракана, но ой-ой скольким проектам она бы помогла.

Sep. 10th, 2007

DMakeev

dmakeev

Evraz.com HandMade.

Уфффф. evraz.com.
В двух словах:

  • несколько мегабайт кода на 3,5 языках (PHP+JS+ActionScript+Smarty).
  • 500 (+/-) человекочасов
  • первое (насколько мне известно) масштабное использование Bitrix+AJAX.

Что сделано:

  • Навигация на сайте сделана через ajax.
    — Вы жмете на ссылку, данные подгружаются, страница не меняется.
    — адресной строке всегда ссылка на текущую страницу, как бы Вы на нее не пришли.
    — функциональность сохраняется и без JavaScript, а значит совершенно дружелюбно поисковым машинам.
    — внедрение JS не потребовало никаких изменений контента и минимальных изменений основного функционала
    — корректно отрабатывают кнопки "Back" и "Forward" (пока что я подобных решений не встречал)

  • Написан свой маленький искуственный интеллект
    Есть три категории пользователей. В зависимости от поведения пользователя и того, какие страницы он посещает, определяется к какой группе он больше подходит. Интерфейс сайта оптимизирован под каждую группу.

  • Блоки главной страницы можно подвигать
    Только сначала нужно зарегистрироваться.

  • На страницах сайта можно порисовать и отправить свои художества друзьям
    Релиз на днях.

  • Сделана своя реализация ключевых слов (а-ля облако тегов)
    http://evraz.com/about/glance, подводим мышку к подчеркнутым словам и видим связанные документы. Естественно это все не руками расставляется - автоматика превыше всего.

  • Добавлены свои два уровня кэширования
    Кэшируем постобработку сгенерированной страницы (подключение AJAX) и полностью обработку страницы (в принципе можно полностью отключить БД и сайт будет работать).

  • Блок "Новое на сайте"
    В правой колонке выводим список всего, что изменялось на сайте за последнее время. В Битриксе это ни с одной стороны не тривиальная задача.

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

  • Нормально живет на одном сервере и при 20`000 хитов в день не создает никакой ощутимой нагрузки.
DMakeev

dmakeev

Страшный зверь Web 2.0

Все чаще и чаще встречаю термин Web 2.0. Причем в самых разных смыслах - мнений о том что это за зверь и с чем его едят - вагон. И если среди разработчиков есть устоявшиеся мнения, то в рядах заказчиков и околовебовской прессы царят полные разброд и шатание. Мол страшный термин это "крупные шрифты" и "облако тегов" на сайте и т.д...

Два слышанных мной основных мнения:
- Web 2.0 — это ajax.
- Web 2.0 — это саморазвивающиеся проекты (социальные сети, комьюнити etc)

Но как-то фиг формализуешь - ЖЖ однозначно саморазвивающийся проект, но с ajax`ом не дружит, веб-интерфейсы гугла сплошь ajax`овые, но не сказал бы что Google.maps сами себя развивают. Однако и то и другое дружно относят к Web 2.0.

Я бы предложил альтернативный подход (сначала чуть многословно):
Мы привыкли к тому что сайт - "взаимосвязанная совокупность HTML-страниц" и основная задача - провести человека за руку по этим страницам чтобы он нашел то что ему нужно и остался доволен. К Web 2.0 обычно относят то что выпригивает из этого определения - то блоки по экрану можно двигать, то контент меняется без перезагрузки, то еще что. ИМХО Web 2.0 - это изначально иной подход к проектированию. Подход, подразумевающий разработку сайта как интерфейса пользователя, а не как совокупности страниц. Интерфейса, наделенного собственнм функционалом (с ajax`ом в качестве инструмента). Интерфейса, ориентированного на взаимодействие с пользователем и меняющегося с помощью пользователя.

Теперь то же самое, но в двух словах: Web 2.0 - подход к проектированию, предполагающий разработку сайта как интерфейса, способного реагировать на действия пользователя и изменяться в зависимости от его действий.

PS Все вышесказанное - ИМХО. Кидание помидоров в комментах приветствуется.

Mar. 15th, 2007


runever

Dexter наступил

Мы его сделали и теперь он с нами.
http://www.dexter.ru/

Краткий список 'разумеется':
- разумеется, он управляем администратором;
- разумеется, теги и ссылки, поставляемые администратором в визуальном редакторе работают во флеш;
- разумеется, у разделов есть свои ссылки, которые можно посылать друзьям;
- разумеется, мы послали подальше все рамки активации Flash в IE;
- разумеется, он уникален в рунете и аналогов ему еще нет

P.S. Модемщиков в жопу.

Previous 10 | Next 10