Полезные хитрости кодинга: То, что приходится каждый день искать в Интернете…

Как использовать генераторы в своем приложении

Недавно возникла необходимость использовать генераторы файлов в своем приложении. В Rails все уже написано и очевидно, что стоит использовать уже готовый код. Вопрос только в том, как использовать код, который достаточно тесно интегрирован в Rails.

Двухчасовые исследования показали, что все достаточно несложно (на примере Rake-файла):

require 'rails/generators'

module Rails
  def self.application
    nil
  end
end

class DocumentScaffoldGenerator < Rails::Generators::NamedBase

  def manifest
    template "templates/document.tex", "src/document.tex"
  end

end

DocumentScaffoldGenerator.source_root(File.dirname(__FILE__))

task :scaffold do
  Rails::Generators.invoke('document_scaffold')
end

Сам манифест генератора пишется с использованием хелперов Thor.

Небольшой monkey-patch в начале нужен, чтобы сказать, что никакого Rails-приложения тут на самом деле нет и не будет.

Вызвать IRB в своем коде

Часто возникает желание в Ruby вызвать IRB где-нибудь в контексте собственного кода для того, чтобы посмотреть или поменять значения переменных, покрутить винтики и гаечки.

Я делаю это при помощи небольшого собственного gem’а:

require 'rubygems'
require 'sky-debug'

a = 123

# вызвать IRB, ему будут доступны все переменные контекста для чтения и изменения
breakpoint binding

puts a

NetCat для Windows

Давно искал версию NetCat для Windows. Очень удобная утилита, и, наряду с Wget и Curl, полностью решает вопросы доступа к сети из командной строки.

Нашел вот версию Джона Кратона, которую тут и выкладываю. Эта утилита определяется антивирусами как not-a-virus:RemoteAdmin.Win32.NetCat, так что либо добавьте ее в исключения Вашему антивирусу, либо удалите антивирус, либо попробуйте сами собрать NetCat :-) . Никакой вирусной активности этот NetCat не проявляет.

Скачать NetCat под Windows.

Изменение заголовка окна PuTTY

Столкнулся с такой проблемой: когда открыто куча удаленных консолей, начинаешь путаться. Особенно, когда нерадивые админы ставят одинаковые имена хостов. Было бы удобно в этом случае задавать какие-то простые и понятные заголовки окон для PuTTY, тогда искать их будет намного легче. И, оказывается, делается это очень легко. Далее »

Еще раз про MD5 и SHA-1

Начну опять в эпическом стиле: недавно нужно было перенести огромный файл между двумя хостами. Как я это делал – это отдельная история. Но после того, как я его перенес, мне нужно было убедиться в его целостности. В UNIX/Linux “все уже украдено до нас”, и утилиты для подсчета MD5 и SHA и прочей мерзости практически всегда идет в базовом дистрибутиве ОС в формате md5sum и sha1sum.

Но обе системы, в которых я переносил файл, были Windows. В сети целая толпа софта, при помощи которого можно посчитать хеши, но не хотелось ставить что-то “левое”, чтобы не переживать на тему затрояненности оного.

Поэтому небольшой поиск привел к следующей утилите:

http://download.microsoft.com/download/c/f/4/cf454ae0-a4bb-4123-8333-a1b6737712f7/windows-kb841290-x86-enu.exe

Это стандартная утилита от Microsoft, позволяющая рассчитывать хеши файлов для проверки их целостности. И никаких гвоздей.

PHP: работа с файлами

На PHP нередко приходится работать с файлами: осуществлять как вывод в файл, так и вывод файла на экран. Нередко, но не настолько часто, чтобы помнить наизусть самые простые и лаконичные способы сделать это. Поэтому приведу эти способы здесь, чтобы в следующий раз не искать.

Вывести файл в поток вывода:

echo file_get_contents("file-name.txt");

Осуществить вывод в файл одной строчкой:

file_put_contents("file-name.txt", "Content");

Как пользоваться git’ом

Так вышло, что любимая система контроля версий в нашей небольшой команде разработчиков – git. Поэтому приведу несколько самых распространенных и используемых ежедневно команд.

Список часто используемых команд git

# создание репозитория
git init

# добавление всех изменений в репозиторий (в т.ч. новых файлов)
git add .

# закрепление всех изменений в репозитории
# (включая изменения, не добавленные командой git add, за исключением новых файлов)
# будет вызван визуальный редактор комментария к коммиту
git commit -a

# закрепление всех изменений в репозитории
# комментарий к коммиту задается в командной строке
git commit -a -m "Сообщение"

# отменить последний коммит, вернув все изменения в проект
# (что-то вроде кнопки undo для последнего коммита)
git reset --soft HEAD^

# текущее состояние рабочего дерева каталогов
git status

# просмотреть внесенные Вами изменения с момента последнего коммита
git diff

# добавить ссылку на удаленный SSH репозиторий
git remote add origin ssh://user@myserver.com/var/git/myapp.git

# удалить ссылку удаленный репозиторий
git remote rm origin

# получение последней версии из источника (удаленного репозитория) и слияние ее с текущей
git pull origin master

# отправка Вашей версии в источник (удаленный репозиторий)
git push origin master

# создание ветви (бранча)
git branch branch_name

# переключение ветви (бранча)
git checkout branch_name

# слияние текущей ветви и с указанной
git merge branch_name

# удаление ветви (бранча)
# ветвь должна быть полностью слита с HEAD
git branch -d branch_name

# безусловное удаление ветви (бранча)
git branch -D branch_name

И более сложные примеры

Создание репозитория и загрузка его на удаленный серевер через SSH:

git init
touch README
git add README
git commit -a -m "Initial commit"
git remote add origin ssh://user@myserver.com/var/git/myapp.git
git push origin master

Создание ветви, изменение и слияние:

git init
git branch test
git checkout test
# ...
# внесение изменений
# ...
git commit -a -m "Branch commit"
git checkout
git merge test
git branch -d test

Установка кода ответа HTTP на PHP

Заголовки HTTP, которые зачастую приходится выводить на PHP:

// Обычный ответ. Все ОК. Иногда нужно выводить этот заголовок, если при использовании rewrite сервером устанавливается код 404.
header('HTTP/1.1 200 OK');

// Страница не найдена. Код 404.
header('HTTP/1.1 404 Not Found');

// Доступ запрещен. Код 403.
header('HTTP/1.1 403 Forbidden');

// Перенаправление. Страница изменила свое местоположение.
// Этот тип перенаправления следует использовать практически всегда, ибо поисковики благодаря ему обновляют адреса страниц в своих индексах.
header('HTTP/1.1 301 Moved Permanently');

// Временное пренаправление.
// Его следует использовать только в одном случае: Ваш скрипт получил POST запрос, обработал его и перенаправляет на страницу с результатом.
header('HTTP/1.1 302 Found');

 // Ошибка на сервере
header('HTTP/1.1 500 Internal Server Error');

// Перенаправление на указанный адрес. Следует использовать с 301 или 302.
header('Location: http://www.example.org/');

// Перенаправление на указанный адрес с задержкой.
header('Refresh: 10; url=http://www.example.org/');
print 'Вы будете перенаправлены через 10 секунд.';

// Принудительное указание языка страницы
header('Content-language: ru');

// Установка времени последнего изменения (для правильного кеширования)
$time = time() - 60; // или filemtime($fn), и т.п.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');

// Заголовок, сообщающий бразуеру, что содержимое страницы не изменилось
header('HTTP/1.1 304 Not Modified');

// Принудительная установка длины cодержимого ответа
header('Content-Length: 1234');

// Заголовки для выдачи окна скачивания файла
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"');
header('Content-Transfer-Encoding: binary');
// ... выдача файла в поток ответа:
readfile('example.zip');

// Отключение кеширования для текущего документа
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Дата в прошлом
header('Pragma: no-cache');

// Установка типа содержимого
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); // текстовый файл
header('Content-Type: image/jpeg'); // изображение в формате JPG
header('Content-Type: application/zip'); // ZIP-файл
header('Content-Type: application/pdf'); // PDF-файл
header('Content-Type: audio/mpeg'); // Аудио MPEG (MP3,...)
header('Content-Type: application/x-shockwave-flash'); // Анимация Flash

// Вывод сообщения авторизации
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Этот текст будет отображается пользователю, если он нажмет';
print '"Отмена" или введет неправильные реквизиты доступа.';

Как посчитать MD5 строки на Ruby или C#

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

Итак, расчет MD5 cтроки на Ruby:

require 'digest/md5'
digest = Digest::MD5.hexdigest("ivan4ik")

Расчет MD5 строки на C#:

private string CreateMD5Hash(string input)
{
    MD5 md5 = System.Security.Cryptography.MD5.Create();
    byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
    byte[] hashBytes = md5.ComputeHash(inputBytes);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < hashBytes.Length; i++)
    {
        sb.Append(hashBytes[i].ToString("X2"));
    }
    return sb.ToString();
}

Делаем анонс из текста

Часто возникает задача сделать анонс из текста, не длиннее какого-то количества символов. Например, для вывода его в списке.

В этом поможет следующий код на Ruby:

def teaser(txt, max_length)
  return txt if txt.length <= max_length-4
  txt.mb_chars.slice(0, max_length-4+1).gsub(/[\s\.\?!,]+\w*$/, '').slice(0, max_length-4).to_s+" ..."
end

Этот код делает "тизер" не длиннее указанного количества символов, при этом не обрывает слова и удаляет лишние знаки препинания.

Обновлено: принимая во внимание то, как до сих пор реализована поддержка Unicode в Ruby On Rails (больше, конечно, в Ruby, чем в Rails), я изменил код. Теперь он поддерживает тексты на всех языках мира и корректно создает любые иноязычные (в т.ч. и на русском) тизеры.

Страница 1 из 212»