Как скачать сайт целиком на Linux или FreeBSD с помощью wget

С помощью wget можно скачивать сайты, включая картинки, всего лишь указав адрес сайта и определенные параметры. wget будет автоматически переходить по ссылкам на сайте и скачивать страницу за страницей. Рассмотрим несколько примеров от простых к более сложным использования wget для скачивания сайтов.

Чтобы скачать сайт целиком с помощью wget нужно выполнить команду:

wget -r -k -l 7 -p -E -nc http://site.com/

После выполнения данной команды в директорию site.com будет загружена локальная копия сайта http://site.com. Чтобы открыть главную страницу сайта нужно открыть файл index.html.

Рассмотрим используемые параметры:

-r указывает на то, что нужно рекурсивно переходить по ссылкам на сайте, чтобы скачивать страницы.
-k используется для того, чтобы wget преобразовал все ссылки в скаченных файлах таким образом, чтобы по ним можно было переходить на локальном компьютере (в автономном режиме).
-p указывает на то, что нужно загрузить все файлы, которые требуются для отображения страниц (изображения, css и т.д.).
-l определяет максимальную глубину вложенности страниц, которые wget должен скачать (по умолчанию значение равно 5, в примере мы установили 7). В большинстве случаев сайты имеют страницы с большой степенью вложенности и wget может просто «закопаться», скачивая новые страницы. Чтобы этого не произошло можно использовать параметр -l.
-E добавлять к загруженным файлам расширение .html.
-nc при использовании данного параметра существующие файлы не будут перезаписаны. Это удобно, когда нужно продолжить загрузку сайта, прерванную в предыдущий раз.

 

Мы рассмотрели лишь одно из возможных применений утилиты wget. На самом деле область применения wget значительно шире и wget обладает большим числом дополнительных параметров. За более подробной информацией обращайтесь к руководству, выполнив в командной строке: man wget.

MySQL Шпаргалки

MySQL шпаргалки

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

Сегодня я решил опубликовать свои шпаргалки, на самые часто встречающиеся ошибки при работе с MySQL.

Делаем бекап
mysqldump -u USER -pPASSWORD DATABASE > /path/to/file/dump.sql

Создаём структуру базы без данных
mysqldump --no-data - u USER -pPASSWORD DATABASE > /path/to/file/schema.sql

Если нужно сделать дамп только одной или нескольких таблиц
mysqldump -u USER -pPASSWORD DATABASE TABLE1 TABLE2 TABLE3 > /path/to/file/dump_table.sql

Создаём бекап и сразу его архивируем
mysqldump -u USER -pPASSWORD DATABASE | gzip > /path/to/outputfile.sql.gz

Создание бекапа с указанием его даты
mysqldump -u USER -pPASSWORD DATABASE | gzip > `date +/path/to/outputfile.sql.%Y%m%d.%H%M%S.gz`

Заливаем бекап в базу данных
mysql -u USER -pPASSWORD DATABASE < /path/to/dump.sql

Заливаем архив бекапа в базу
gunzip < /path/to/outputfile.sql.gz | mysql -u USER -pPASSWORD DATABASE
или так
zcat /path/to/outputfile.sql.gz | mysql -u USER -pPASSWORD DATABASE

Создаём новую базу данных
mysqladmin -u USER -pPASSWORD create NEWDATABASE

Удобно использовать бекап с дополнительными опциями -Q -c -e, т.е.
mysqldump -Q -c -e -u USER -pPASSWORD DATABASE > /path/to/file/dump.sql, где:

  • -Q оборачивает имена обратными кавычками
  • -c делает полную вставку, включая имена колонок
  • -e делает расширенную вставку. Итоговый файл получается меньше и делается он чуть быстрее

Для просмотра списка баз данных можно использовать команду:
mysqlshow -u USER -pPASSWORD

А так же можно посмотреть список таблиц базы:
mysqlshow -u USER -pPASSWORD DATABASE

Для таблиц InnoDB надо добавлять —single-transaction, это гарантирует целостность данных бекапа.
Для таблиц MyISAN это не актуально, ибо они не поддерживают транзакционность.

Подробнее

Общие факты

  • Полезно под каждую базу на боевом сервере создавать своего пользователя
  • Кодировка базы может быть любой, если она UTF8
  • В большинстве случаев лучше использовать движок InnoDB
  • В php лучше забыть про сильно устаревшее расширение mysql и по-возможности использовать pdo или mysqli
  • Новую копию MySQL всегда можно настроить и оптимизировать
  • Без особой нужды не стоит открывать MySQL наружу. Вместо этого можно сделать проброс портов
    ssh -fNL LOCAL_PORT:localhost:3306 REMOTE_USER@REMOTE_HOST

Работа с данными

Числа
  • На 32-битных системах практически нет смысла ставить для типа INTEGER свойство UNSIGNED, так как такие большие числа в php не поддерживаются.
    На 64-битных системах, php поддерживает большие числа, вплоть до MySQL BIGINT со знаком.
  • Связанные таблицы («Foreign keys») должны иметь полное сходство по структуре ключей. Т.е. если у нас на одной таблице для поля указано «INTEGER UNSIGNED DEFAULT 0 NOT NULL» то и на другой должно быть указано аналогично
  • Для хранения булевых значений, нужно использовать TINYINT(1)
  • А деньги лучше хранить в DECIMAL(10, 2), где первое число обозначает количество всех знаков, включая запятую, а второе — количество знаков после запятой. Итого, у нас получится что DECIMAL(10,2) может сохранить 9999999,99
Строки
  • В старых версиях (до 5.0.3) VARCHAR была ограничена 255 символами, но сейчас можно указывать до 65535 символов
  • Помните, что тип TEXT ограничен только 64 килобитами, поэтому что бы сохранять «Войну и Мир» пользуйтесь «LONGTEXT»
  • Самая правильная кодировка для вашей БД UTF8
Даты

Не забывайте, что

  • DATE, TIME, DATETIME — выводятся в виде строк, поэтому поиск и сравнение дат происходит через преобразование
  • TIMESTAMP — хранится в виде UNIX_TIMESTAMP, и можно указать автоматически обновлять колонку
  • Сравнивая типы данных DATETIME и TIMESTAMP, не забывайте делать преобразование типов, например:
    SELECT * FROM table WHERE `datetime` = DATE(`timestamp`)
Перечисления
  • Для перечислений правильно использовать тип ENUM
  • Правильно пишется так: ENUM(‘мама’, ‘мыла’, ‘раму’)
  • Можно ставить значение по-умолчанию, как и для любой строки
  • В базе поле с перечислением хранится как число, поэтому скорость работы — потрясающе высокая
  • Количество перечислений ~ 65 тысяч

dev.mysql.com/doc/refman/4.1/en/storage-requirements.html
help.scibit.com/mascon/masconMySQL_Field_Types.html

Отладка

  • Если запросы тормозят, то можно включить лог для медленных запросов в /etc/mysql/my.cnf
  • А потом оптимизировать запросы через EXPLAIN
  • И наблюдать за запросами удобно через программу mytop

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

Прекрасные консольные команды

Вот нашел отличный сборник полезных консольных комманд =)

http://www.commandlinefu.com/commands/browse/sort-by-votes

Вот выдежки

sudo !!
Выполнить последнюю команду еще раз

python -m SimpleHTTPServer
Запустить встроенных HTTP сервер в питоне, и начать предоставлять доступ к текущей директории на 8000 порту (удобно когда надо файл скачать с сервака например)

ssh -N -L2001:localhost:80 somemachine
Запустить туннель между текущей машиной, и удаленной на 2001 порту. Теперь к внешней машине:80 можно обращаться через localhost:2001

curl ya.ru
Показать на экране содержимое траницы http://ya.ru

curl -u user:pass -d status=»Tweeting from the shell» http://twitter.com/statuses/update.xml
Пост твита через коммандную строку (уже не работает =(( )

И много чего еще там есть. Классный сайт!

Asterisk D-link DPH-150S

Я ВСЕ СЛЫШУ!!!

Для мониторинга, что творится в квартире, сначала использовал простую web-камеру и программку WebCamPro.
На рабочем сервере сделал в конфиге Asterisk следующее:

exten => 300,1,SIPAddHeader(Call-Info: answer-after=0)
exten => 300,n,Dial(SIP/300@home,,tT)

на домашнем, естетсвенно, стоит такая настройка:

exten => _3XX,1,Dial(SIP/${EXTEN},,tT)

Звоним …. и ничего. Поначалу расстроился, что данного функционала в Dlink DPH-150S просто нет. Но потом перенес строку SIPAddHeader(Call-Info: answer-after=0) на домашний сервер и все прекрасно заработало. Точнее сделал вызов на конкретный номер, чтобы не пугать всех и вся 🙂

exten => _3XX,1,Dial(SIP/${EXTEN},,tT)
exten => 333,1,SIPAddHeader(Call-Info: answer-after=0)
exten => 333,n,Dial(SIP/300,,tT)

Стоит на работе позвонить на 333 — попадаю домой и слышу что там творится.

НАС УТРО ВСТРЕЧАЕТ ПРОХЛАДОЙ.

В один прекрасный день забыл зарядку на работе. Все бы ничего — но сотовый разрядился ночью и … проспал КОНКРЕТНО на работу (мои как раз на даче были).

Что ж — есть «маленький» помощник в лице астера.

Ставим по cron-у генерацию call-файла примерно такого содержания:

Channel: Local/333@good_morning
MaxRetries: 0
RetryTime: 600
WaitTime: 60
Context: good_morning1
Extension: s
Priority: 1
Archive: yes

а далее в диалплане:

[good_morning]
exten => 333,1,SIPAddHeader(Call-Info: answer-after=0)
exten => 333,n,Dial(SIP/300,,tT)

[good_morning1]
exten => s,1,Answer
exten => s,n,Playback(pora_na_rabotu)

Все. Работает. Ну, еще, поковырявшись в Google, нашел примеры информатора погоды и будильник не просто проговаривал приветствие, но и прогноз на текущий день.

ЧЕГО ЕЩЕ ЖЕЛАЕТЕ?

Будильник будильником, но… ХОЧЕТСЯ БОЛЬШЕГО.

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

#!/usr/bin/perl
########################################################################
#
# $Id: google-voice-search.pl,v 1.1 2011-04-13 06:06:39 gosha Exp $
#
# Copyright (c) 2011 Okunev Igor <igor[at]prv.mts-nn.ru>
#
########################################################################

require LWP::UserAgent;

#my ( $file ) = @ARGV;

my ( $url, $use_converter );

my $lang=»ru»;
my $file=»/tmp/record.wav»;

unless ( $file ) {
die «Usage: $0 file.flac lang\n\twhere lang is ru or en\n»;
}

if ( lc($lang) eq ‘ru’ ) {
$url = «https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU»;
} else {
$url = «https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-US»;
}

#
# to FLAC
#
unless ( $file =~ /\.flac$/i ) {
system «ffmpeg -y -i $file $file.flac 2> /dev/null»;
if ( $? ) {
die «Can’t convert file $file to $file.flac: $?\n»;
} else {
$file .= ‘.flac’;
$use_converter = 1;
}
}
                                        
my $file_info = `file $file`;
if ( $file_info =~ /FLAC audio.*\s(\d+)\s*kHz/ ) {
$file_info = $1.’000′;
} else {
unlink $file if $use_converter;
die «Incorrect FLAC file: $file_info\n»;
}

open( FILE, «<$file» ) || die «Can’t open input file[$file]: $!\n»;
undef $/; my $audio = <FILE>; $/ = «\n»;
close(FILE);

unlink $file if $use_converter;

my $ua = LWP::UserAgent->new( debug => 1 );

my $response = $ua->post($url, Content_Type => «audio/x-flac; rate=$file_info», Content => $audio);

if ( $response->is_success ) {
print $response->content;
my $result=$response->content;

my($res1,$res2,$res3,$res4,$res5)=split(«:»,$result);
$_=$res5;
s/\»confidence\»//;
s/\»//;
s/\»//;
s/,//;

open(OUTFILE,»>/tmp/record.txt»);

print OUTFILE $_;
close(OUTFILE);

} else {
use Data::Dumper;
delete $response->{‘_request’}->{‘_content’};
print STDERR Dumper($response);
}

Теперь модифицировал диалплан:

exten => s,n(cikl),Playback(chto_xotim)
exten => s,n,Record(/tmp/record.wav,,5,k)
exten => s,n,AGI(/var/www/cgi-bin/voice.pl)
exten => s,n,Set(TEST=${FILE(/tmp/record.txt)})
exten => s,n,NoOp(${TEST})
exten => s,n,GotoIf($[«${TEST}»=»нет»]?hang)
exten => s,n,Goto(cikl)
exten => s,n(hang),Hangup

К сожалению пришлось использовать обмен информацией через промежуточный файл, а не функцией CURL — скрипт отказывался нормально стартовать через http-запрос.

Ксати, обратите внимание на проверку на слово НЕТ — Asterisk прекрасно справился с задачей.

Вот так ручками сделал седе некий аналог Siri 🙂 Причем в сам perl-скрипт можно добавить собственные обработчики распознанного текста и возвращать в астер не текст, а МЕТКИ, которые используете в диалплане.

php ругается на autoconf

Если при установке PHP у вас возникли проблемы с autoconf

то поможет не сложное лекарство.

===>   php5-bcmath-5.3.3_2 depends on file: /usr/local/bin/phpize - found
===>   php5-bcmath-5.3.3_2 depends on file: /usr/local/bin/autoconf-2.68 - found

===>  PHPizing for php5-bcmath-5.3.3_2
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
autoconf: required version 2.68 not found

*** Error code 1

Выполните эти команды, и после этого сборка пойдет как надо!

cd /usr/ports
make update
pkg_delete -xr "^auto*"