Архив рубрики: Веб

Правильный тип для офисных файлов

Перловый микрофреймворк Mojolicious::Lite умеет сам выдавать существующие файлы, но при этом не все из них получают верный тип содержимого Content-type: некоторые файлы прикидываются обычными текстовыми (text/plain), другие же вообще не имеют никакого типа — браузер такие файлы может воспринимать как угодно. В состав фреймворка входит модуль Mojolicious::Types, в котором определены MIME-типы для наиболее популярных (most common) расширений файлов:

appcache -> text/cache-manifest
atom     -> application/atom+xml
bin      -> application/octet-stream
css      -> text/css
gif      -> image/gif
gz       -> application/x-gzip
htm      -> text/html
html     -> text/html;charset=UTF-8
ico      -> image/x-icon
jpeg     -> image/jpeg
jpg      -> image/jpeg
js       -> application/javascript
json     -> application/json;charset=UTF-8
mp3      -> audio/mpeg
mp4      -> video/mp4
ogg      -> audio/ogg
ogv      -> video/ogg
pdf      -> application/pdf
png      -> image/png
rss      -> application/rss+xml
svg      -> image/svg+xml
txt      -> text/plain;charset=UTF-8
webm     -> video/webm
woff     -> font/woff
woff2    -> font/woff2
xml      -> application/xml,text/xml
zip      -> application/zip

странно, но среди них нет ни одного, относящегося к офисным пакетам. На сайте Microsoft | Developer можно найти список типов — Office 2007 File Format MIME Types for HTTP Content Streaming. Чтобы не задумываться, какие же из этих типов брать, можно сохранить все — если есть какой-нибудь конфигурационный файл, он вполне подойдёт для хранения такого списка. В моём случае конфигурационные файлы обычно в формате YAML — это удобно.

---
# ... ещё какие-нибудь параметры

# MS Office types
types:
    rtf:    application/rtf
    doc:    application/msword
    dot:    application/msword
    docx:   application/vnd.openxmlformats-officedocument.wordprocessingml.document

Где-нибудь перед запуском приложения надо добавить типы (допустим, конфигурация приложения доступна через $config)

while ( my ( $ext, $type ) = each %{ $config->{'types'} } ) {
    app->types->type($ext => $type);
}

Правда, при выдаче файла тип его содержимого придётся всё-таки указать явно, иначе Mojolicious вернёт тип только для знакомых файлов, а для офисных будет undef

my $type = $self->app->types->mapping->{$ext}->[0];
if (my $asset = $self->app->static->file("/$path/$id.$ext")) {
    $self->res->headers->content_type($type);
    return $self->reply->asset($asset);
}
else {
    return $self->reply->not_found;
}

Теперь и офисные файлы возвращаются нормально.

Надо ругаться в боевом режиме

В состав перлового микрофреймворка Mojolicious::Lite входит класс Mojo::Log, который не просто пишет сообщения в лог, а ещё и учитывает важность сообщений — в отладочном режиме пишет много, а боевом — мало. Обнаружилось, что сообщения об ошибках имеют тот же класс debug, что и остальные сообщения

[Tue Nov 13 12:25:51 2018] [debug] Format html
[Tue Nov 13 12:25:51 2018] [debug] 200 OK (0.076118s, 13.137/s)
[Tue Nov 13 12:25:53 2018] [debug] GET "/some/url"
[Tue Nov 13 12:25:53 2018] [debug] Template "not_found.development.html.ep" not found
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "not_found.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "layouts/error.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "layouts/admin.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "search_form_navbar.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Format html
[Tue Nov 13 12:25:53 2018] [debug] 404 Not Found (0.004841s, 206.569/s)

из-за чего при запуске в продакшне под реальной нагрузкой в лог не попадает почти ничего — например, там нет сообщения об ошибках 404 Not Found.

Возможно, где-нибудь во внутренностях Mojo можно исправить такую ситуацию, но мы пойдём другим путём — применим хук after_dispatch:


hook after_dispatch => sub {
    my $self = shift;
    my $req  = $self->req;
    my $res  = $self->res;

    if ( $res->code >= 400 ) {
        $self->app->log->error(join ' ',
            '"' . $req->method . ' ' . $req->url . '"',
            $res->code,
            $req->headers->referrer || '-',
            '"' . $req->headers->user_agent . '"',
        );
    }
};

after_dispatch

Результат — в логе появились сообщения об ошибках:

Sending children hup signal
[Tue Nov 13 12:30:46 2018] [error] "GET /none" 404 - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
[Tue Nov 13 12:44:50 2018] [error] "GET /SW/Rplayer.html" 404 - "Mozilla/5.0 (compatible; Linux x86_64; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)"

Инструменты разные — методы похожие

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

  • Вместо  перла — PHP,
  • Модули тоже лежат рядом со своим кодом, но управляются не картоном, а через composer,
  • Композер и тесты может запустить (composer test), и отладочный сервер (composer start). Но можно для однообразия для обоих языков сделать Makefile и выполнять нужные действия командой make. Например, у меня запуск тестов — всегда make test, чтобы не путаться.
  • Вместо Mojolicious::Lite — микрофреймворк Slim. Для быстрого старта — Slim-Skeleton.
  • В шаблонах вместо Embedded Perl — Twig.
  • Если сайт работает через PHP-FPM, то нет нужды пинать демона каждый раз, как обновится код — он сам обрабатывает подобную ситуацию. Развёртывание свежей версии простого веб-приложения сводится к трём действиям: обновление рабочей копии (svn up либо git pull), разрешение зависимостей (composer install) и на всякий случай запуск тестов.

Слон и код

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

Почти что Перл с Апачем

Новости географии: в одном люксембургском углу находится никому не известная деревня Шенген, ближайшая к ней железнодорожная платформа, буквально на другом берегу реки — Perl (по-русски всё-таки Перль), это же имя носит и муниципалитет (в других переводах — коммуна), и крупнейший его населённый пункт. А рядом с ними — Apach, но по-русски это не Апач, а, если верить википедии, Апаш, хотя, думаю, немцы могут прочесть и как Апах. При этом все три эти деревни — в разных странах.

Карта

Не скайп

Скайп на моём компьютере теперь выглядит так:

Скайп не работает

и, понятно, не работает. А телеграммы в соседней вкладке вполне успешно ходят. Значит, теперь и скайпом придётся пользоваться через прокси.

Как задать ширину блоков, когда есть LESS и Bootstrap 3

Чтоб не замусоривать код веб-страниц классами, которые предлагает фреймворк Bootstrap, лучше добавить свойства из этих классов к своим классам либо id, которые и так уже присутствуют в коде — для этого в CSS-препроцессоре LESS есть функция extend. Однако оно не всегда работает: код


.logo {
  &:extend(.col-xs-6);
  &:extend(.col-sm-4);
  &:extend(.col-md-6);
}

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

Работает другое:


.logo {
  .make-xs-column(6);
  .make-sm-column(4);
  .make-md-column(6);
}

Результат —


.logo {
  float: left;
  width: 50%;
  position: relative;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
}
@media (min-width: 480px) {
  .logo {
    float: left;
    width: 33.33333333333333%;
  }
}
@media (min-width: 960px) {
  .logo {
    float: left;
    width: 50%;
  }
}

Рецепт найден на https://www.sitepoint.com/less-beyond-basics-bootstrap-mixins-library/

На ильменском сайте — как в википедии

На сайте Ильменского фестиваля к длинным страницам, в тексте которых попадаются заголовки, автоматически добавляется содержание — можно быстро перейти куда-нибудь вниз. Подобная штуковина есть в CMS MediaWiki (на ней сделана Википедия) и в багтрекере Redmine. А теперь — и на ильменском сайте.

Содержание страницы сайта Ильменского фестиваля

Увидеть такое содержание можно на странице с программой фестиваля — http://ilmeny.org/doc/2017/program

Подсветка синтаксиса LESS- и SCSS-файлов в geany

Пробую на работе писать код в geany — он в отличие от Комодо, Атома и Вижл Студио Кода сделан сам по себе, а не из браузера и поэтому гораздо шустрее. Имеющаяся у меня версия 1.24.1, вышедшая почти три года назад (да, я знаю, что есть и более свежие, но у меня дебиан) не подсвечивает синтаксис в LESS- и SCSS-файлах, а при ручном указании типа (Document → Set Filetype → Markup Languages → Cascading Stylesheet) подсветка хоть и включается, но ругается на особенности синтаксиса, выходящие за рамки обычного CSS.

Решение нашлось на http://superuser.com/questions/344441/less-syntax-highlighting-in-geany:

1. В файле ~/.config/geany/filetype_extensions.conf меняем

CSS=*.css

на

CSS=*.css;*.less;*.scss;

Если такого файла нет, его можно взять из /usr/share/geany (в дебиане — так).

2. В файл ~/.config/geany/filedefs/filetypes.css (который тоже можно взять из /usr/share/geany) добавляем

[lexer_properties]
lexer.css.less.language=1

3. Если geany уже запущен — перечитываем конфигурацию: Tools → Reload Configuration

Подсветка синтаксиса LESS-файлов в geany

Результат — подсветка включается автоматически при открытии LESS- и SCSS-файлов и всякие специфические штуки отображаются нормально: geany теперь не ругается на вложенность правил, на селекторы с амперсандом, на комментарии в стиле C++ (две косые черты), на LESS-переменные с @собакой и на SCSS-переменные с $долларом.

Statt zu schlafen

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

Могу:

  • Программировать на Перле — как древние CGI-приложения, так и современные, с использованием фреймворков Mojolicious, Dancer, Catalyst.
  • Программировать на PHP: в основном допиливать существующие приложения, а не писать с нуля что-то большое.
  • Настраивать CMS Drupal и WordPress, а также дорабатывать их темы оформления.
  • Настраивать и дорабатывать Open Journal Systems, включая реализацию многоязычности имён — делал это в OJS 2.4.2, 2.4.7.1, 2.4.8.1, думаю, и в Open Conference Systems смогу реализовать.
  • Кроссбраузерно верстать веб-страницы.
  • Немножко программировать на Руби (в том числе, с использованием Ruby on Rails) — наверное, на юниорском уровне.
  • Немножко программировать на ЯваСкрипте — как голый JavaScript, так и с jQuery.
  • Постоянно внушать коллегам необходимость использования багтрекера и системы контроля версий.
  • (хоть и не считаю это основными профессиональными навыками) фотографировать, петь, аккомпанировать на шестиструнной гитаре, водить легковой автомобиль, быть Дедом Морозом, набирать ноты в MuseScore и LilyPond — медленно, но красиво.

1000 рублей

Хочу от 15 USD / 1 kRUB в час.


Statt zu schlafen (нем.) — вместо того, чтобы спать

Точка конф

Apache 2.2 у маленьких конфигурационных файлов, вызываемых из основного, не использует расширение (хотя и не запрещает его применячть, конечно же). Старый Апач 1.3 — использовал. Как выяснилось методом тыка и чтения stackoverflow, новый Апач 2.4 — снова использует, во всяком случае команды a2ensite something и a2dissite something пытаются найти файл sites-available/something.conf. Да и в остальных каталогах /etc/apache2/*-available — куча conf-файлов.

Кусок конфигурационного файла

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