Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2012-07-31

July 30, 1947

30 июля 1947 года родился великий человек — Arnold Schwarzenegger.
Конечно, не такой великий как, скажем, Александр Македонский или Наполеон. Но для наших дней вполне велик. Образец для подражания, отличный мужик, сильный во всех отношениях.

Славься, Железный Арни!

А вы знаете, что его фамилие можно толковать как «черный пахарь»?

За цынк спасибо Гоблину (oper.ru/news). Если бы не он, я бы профукал юбилей.

2012-07-30

libnpjp2.so

Вчера понадобился мне java-плагин в браузере (Firefox, Chrome on Debian Wheezy). Хвать — а нету. Пришлось ставить JRE и прописывать плагин (libnpjp2.so) в нужные папки. В интернетах есть 100500 описаний этого процесса, поэтому не буду заострять на нем внимание. Но один момент показался мне интересным.

Как поставить JRE, утянутую с сайта Oracle? Скачать пакет (в моем случае jre-7u5-linux-x64.tar.gz) и натравить на него make-jpkg. Типа так
$ fakeroot make-jpkg  jre-7u5-linux-x64.tar.gz
На выходе будет deb пакет oracle-j2re1.7_1.7.0+update5_amd64.deb устанавливаемый обычным для Дебиана способом.

Волшебная утилита.

2012-07-28

В тулбокс веб-разработчика

Мастхэвные для веб-разработчика утилиты командной строки: curl, siege, ngrep и компания

Life as a web developer can be hard when things start going wrong. The problem could be in any number of places. Is there a problem with the request your sending, is the problem with the response, is there a problem with a request in a third party library you're using, is an external API failing? There are lots of different tools that can make our life a little bit easier


и перевод статьи, несколько надмозговый, но лучше, чем никакого

Жизнь веб-разработчика омрачена сложностями. Особенно неприятно, когда источник этих сложностей неизвестен. То ли это проблема с отправкой запроса, то ли с ответом, то ли со сторонней библиотекой, то ли внешний API глючит? Существует куча различных прилад, способных упростить нам жизнь


в каментах упоминаются еще

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

Продвинутый роутер

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

If you follow this guide you will be able to set up the Open Source (free) firewall pfSense. You will be able to have a separate WiFi LAN subnet with access to the internet that cannot access the internal and seperate LAN.

This guide is intended for users who are from the Linksys, Netgear, D-link etc. firewall/router background. No experience is needed with FreeBSD or Linux to install and run pfSense. When you are finished, management of pfSense will be from a web interface just like any of the SOHO firewall/router appliances. The pf in pfSense stands for 'Packet Filter'.



Как пример для применения приводится случай, когда хочется пускать всех в Интернет через вайфайную точку доступа, но при этом не давать кому попало доступа к своей локальной сетке.

2012-07-27

Не всякому слову верь

Если тебе кажется, что за тобой следят, это еще не значит, что у тебя паранойя.
Два эпизода одного моего дня.

Уно.
Понадобилось мне собрать комбо ArcGIS SDE 10 + Postgres. Впервые в таком составе. Пошел на разведку
читаю
PostgreSQL 8.4.1 (32-bit) + Windows Server 2003 Standard, Enterprise & Datacenter (32-bit); Supported Add-On: PostGIS 1.4.0
Нормально, мой вариант.
Утянул Постгрес 8.4, поставил, запустил. Пора ставить ArcGIS SDE.

Запускаю установщик SDE, звенит первый звоночек — на первом же шаге визарда мне предлагают установить Постгрес 8.3. Почему звоночек? Потому как уже понятно, что весь пакет SDE изначально заточен под Постгрес 8.3, следовательно, с другими версиями будут проблемы, несмотря за заверения о совместимости, виденные ранее. Но мы не ищем легких путей, сказано 8.4, значит 8.4. Продолжаю установку SDE, отказавшись от установки Постгреса 8.3.
Как и следовало ожидать после первого звонка, визард на каждом втором шаге сбоил, благо в хелпе к установщику подробно расписано, как сделать вручную все, что делает визард.

Лично мне пришлось вручную сделать tablespace;
скопировать 
c:\Program Files\ArcGIS\ArcSDE\pgexe\pg841_st_lib\libst_raster_pg.dll
c:\Program Files\ArcGIS\ArcSDE\pgexe\pg841_st_lib\st_geometry.dll
в
c:\PostgreSQL\8.4\lib\
скопировать
c:\Program Files\ArcGIS\ArcSDE\pgexe\bin\sg.dll
c:\Program Files\ArcGIS\ArcSDE\pgexe\bin\pe.dll
в
c:\PostgreSQL\8.4\bin
и создать службу
C:\Program Files\ArcGIS\ArcSDE\pgexe\bin> sdeservice -o create -H "c:\Program Files\ArcGIS\ArcSDE\pgexe" -d postgresql,postgresql-8.4 -p 12345678 -i esri_sde

Все это не с первой попытки и с выяснениями «а что, собственно говоря, происходит». К окончанию процесса я неоднократно пожалел, что поставил 8.4 по итогам разведки.


Дос.
На ArcGIS Desktop 10 надо поставить service pack 5. Не вопрос. Качаем, запускаем... получаем невнятный отлуп инсталлера в диалоговом окошке. На третий раз я догадался заглянуть в Event viewer винды, где прочел

The installation of z:\ag\ArcGISDesktop10sp5.msp is not permitted due to an error in software restriction policy processing. The object cannot be trusted

Вы не поверите, но это значит, что винде не хватило нефрагментированной виртуальной памяти для проверки цифровой подписи! Вот уж воистину, толково придумали. Кстати, было еще такое из той же серии — blob-ы в MS SQL Server не лезли.
Что смешно, увеличение оперативной памяти до 4 гигабайт (при размере файла сервиспака в 480 мегабайт) проблему не решает. Решает только отключение проверки подписи

This problem occurs if the Windows Installer process has insufficient contiguous virtual memory to verify that the .msi package or the .msp package is correctly signed.
Click Start, click Run, type control admintools, and then click OK.
Double-click Local Security Policy.
Click Software Restriction Policies.

Note If no software restrictions are listed, right-click Software Restriction Policies, and then click Create New Policy.
Under Object Type, double-click Enforcement.
Click All users except local administrators, and then click OK.
Restart the computer.
...
Notes
The workaround may not work in an Active Directory domain environment. In an Active Directory domain environment, a domain policy refresh operation will overwrite the local Software Restriction Policies.
Adding more RAM to the computer will not resolve the problem.

Перезагрузка не потребовалась, пак установился после применения рецепта. А файл хотфикса, на который идет сцыль в статье, найти не получилось. Статья сгнила. Да и верно, нормальные пацаны уже давно вин 2008 мучают, нечего тут на 2003 сервере засиживаться.

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

2012-07-25

Польза монетизации

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

Мы все, включая инвесторов, отлично отдаём себе отчёт, что успех nginx на 100% связан с его моделью open source проекта. Никто в здравом уме и трезвой памяти менять в этом смысле или ухудшать ничего не будет. Наоборот, планируем улучшать.

Что нами уже сделано и делается для nginx как открытого проекта в рамках компании:

Введён в строй официальный багтрекер;
Активно перерабатывается и приводится в порядок документация;
Растёт количество разработчиков в команде, занимающихся разработкой nginx;
Nginx уже начал развиваться динамичнее: больше нового кода, быстрее исправляются накопившиеся и вновь обнаруживаемые ошибки;
В процессе формирования находится релиз-цикл и план развития nginx на ближайшее время;
Силами компании началась подготовка бинарных пакетов для популярных дистрибутивов Linux, которые выпускаются в день релиза.


Никакого вреда кроме пользы. Для всех.

2012-07-24

MFP

Интересное дела получаются, когда годами наработанные рефлексы перестают приносить пользу. Что может быть естественнее, чем тянуть парус назад в то время, когда ветер тянет его вперед (чуть не забыл, я о windsurfing)? Оно, конечно, естественно, но вредно. И от этого рефлекса надо отучаться, желательно сразу.
Если тянуть парус назад, то при любой достаточно резкой смене ветра тушка исполняет кувырок назад с доски, в силу потери равновесия. Поэтому, чтобы не кувыркаться а уверенно стоять на доске, парус надо тянуть не на себя а вниз по мачте. Создавая mast foot pressure.
На словах просто, на деле же приходится постоянно контролировать свои движения. Ибо рефлекс потому так и называется, что это бессознательная реакция.

Ключи для sailing position:
  • из положения Т-position, вы начинаете поворачивать голову, ища глазами то место откуда на вас дует ветер, вес тела на задней согнутой ноге
  • вслед за поворотом головы поворачивают плечи и бедра, до положения пока грудь не будет развернута на нос доски, а передняя стопа развернута вдоль доски, касается мастфута внутренним сводом и пальцы ориентированы точно на нос доски
  • расслабленная кисть передней руки подтягивает мачту к груди и удерживает в вертикальном положении, локоть передней руки направлен вниз, строго вниз, вы фокусируете свое внимание на локте
  • продолжая смотреть на линию ветра, вы на ощупь, не глядя на парус, спокойно поднимаете расслабленную кисть задней руки к вашему заднему плечу
  • спокойно положите вашу расслабленную заднюю кисть руки сверху на гик напротив вашего заднего плеча
  • обе руки лежат на гике расслабленно, как на клавиатуре компьютера, большие пальцы сверху гика, локти направлены вертикально вниз, пальцы могут шевелиться, чтобы избежать излишне сильного зажимания гика
  • если ветра мало и доска еще не начала движение, можем «подтолкнуть» доску к движению: еще сильнее потянем локти вниз, передняя кисть немного подаст мачту вперед к носу и на подветренный борт, задняя кисть потянет гик к себе, ноги немного сильнее согнуться, чтобы сохранить баланс при старте
  • доска начнет двигаться и наберет ход, парус станет легче, можно немного выпрямиться и встать прямо и расслабленно, не отпуская мачту и гик далеко от себя


Забота о давлении на мастфут (Мast Foot Pressure MFP):
  • передней рукой поддерживаем постоянное вертикальное положение мачты, расслабленная кисть тянет гик вертикально вниз, локоть тянет гик вертикально вниз
  • задняя рука поддерживает постоянное давление на гик, расслабленная кисть задней руки тянет гик вниз и вперед к носу доски, локоть тянет гик вертикально вниз, гик должен быть в горизонтальной плоскости
  • спина должна быть прямой, ноги сильно согнуты
  • таким образом, мы не позволяем парусу «убегать» от нас на расстоянии вытянутой руки и нарушать наш баланс
  • как только доска начнет двигаться и парус станет легким по ощущениям, вы можете встать в более естественную позу и выпрямить ноги и руки


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

Геопроцессинг

Прекрасная сводная таблица случаев применения условного оператора в геопроцессоре от Esri.


2012-07-23

Blender

Blender is the free open source 3D content creation suite.
Проект неслабо развивается. Оказывается, уже довольно давно в Блендере есть инструмент «скульптура». Вот, к примеру, видеоурок по лепке человеческого торса:


Sculpting a Male Human Bust in Blender from CG Cookie on Vimeo.


Но несмотря на такую крутизну, при изготовлении DOOM3 дизайнеры пользовались пакетом Maya; Rage делали с помощью modo. Блендером почему-то не пользовались.

2012-07-22

Вот это портабельность

LLVM реально зажигает. Народ, пользуясь оказией такое вытворяет, просто волосы дыбом:

Доступен релиз проекта Emscripten 1.4, в рамках которого развивается компилятор, способный преобразовать байткод LLVM в представление на языке JavaScript. Байткод LLVM может быть сгенерирован из исходных текстов на Cи/Си++ при помощи компиляторов lvm-gcc и clang, а также из кода на любом другом языке программирования для которого имеется LLVM-фронтэнд. После компиляции на выходе получается скрипт на языке JavaScript, который может быть выполнен внутри web-браузера, используя только штатный JavaScript-движок, без необходимости задействования дополнительных плагинов.
был выбран готовый декодер H.264, написанный на языке Си, который был упрощён, преобразован в биткод LLVM и транслирован в JavaScript при помощи компилятора Emscripten. Результат оказался впечатляющим - используя только штатные оптимизации Emscripten удалось достигнуть производительности декодирования видео (480x270) в браузере с частотой около 30 кадров в секунду на обычном ноутбуке.


Это что же получается, довольно большой класс программ на C/C++ можно выполнять внутре браузера? А то и целую юниксоподобную ось в браузере поиметь. Достаточно сишные исходники прогнать через LLVM+Emscripten и готов пельмешек.
До чего дошел прогресс.

2012-07-20

6 лет назад

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

А конкретно вот что (материалы из старой папки).

Типа предисловие.

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

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

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

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

Простейший вариант веб сервера на Java

Любое веб приложение делится минимум на две части — клиент (работает в браузере пользователя) и сервер. Клиента мы рассматривать не будем, не здесь. Рассмотрим сервер.
Начинается сервер с обработчика протокола HTTP (Apache HTTPD, MS IIS). Его задача (основная) получить от клиента HTTP запрос и выдать ответ, обычно — текст HTML страницы.
Дабы выдаваемые страницы были "живыми" содержимое надо генерировать программно. Нивапрос — веб сервер по HTTP запросу может определить, что надо запустить некую программу, например PHP, которая и сгенерирует страницу.

А теперь забудем про PHP и представим, что веб сервер - это некая ява-машина (не Java runtime), под управлением которой запускаются и работают ява-программы, называемые servlet (сервлет).

Java-программы крутятся или под сервлет-контейнером (например Tomcat), или под сервером приложений (например JBoss). Сервлет контейнер, он же веб-контейнер это некий продвинутый (в сторону поддержки явы) HTTP демон. Сервер приложений - это очень сложный и могучий сервлет-контейнер, про СП пока не будем. Таким образом, имеем некую среду исполнения ява-программ (сервлетов), предоставляющую сервлетам возможность отвечать на запросы клиентов.

Сервлет — это просто Java-класс, реализующий интерфейс javax.servlet.Servlet. В случае веб применения, сервлет чаще всего наследуется из класса javax.servlet.http.HttpServlet. Веб-приложение может содержать произвольное количество классов сервлетов. Также, веб-приложение содержит xml-файл, где заданы соответствия URL и имен классов сервлетов.

Когда сервлет-контейнер получает HTTP-запрос (например, http://domain.com:8080/webapp/servlet/name/), он находит соответствующее запросу веб-приложение (webapp) и загружает соответствующий класс сервлета (ища имя класса сервлета, соответствующего URI='/servlet/name/').

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

Технология JSP (Java Server Pages) является прямым расширением сервлетов. И смахивает она на использование PHP: JSP-файл представляет собой HTML-страницу, с Java-вставками в специальных тегах. Перед первым запуском (или во время) JSP компилируются в обычные сервлеты.

говорится о том, что сервлеты это инструмент для низкоуровневого (относительно) решения задачи "отработка запроса клиента", в случае, если частые изменения дизайна страниц не требуются. В то время как JSP это ориентированнй скорее на представительскую (presentation) сторону способ сделать страницы динамическими. Банально удобнее дизайнить внешний вид страниц. БОльшее разделение логики и внешнего вида.

Контейнер сервлетов поддерживает всё необходимое для реализации достаточно серьезного веб приложения: управление заголовками HTTP, аутентификацией, механизм сессий (с использованием кукисов - cookie) и прочие удобные и стандартные штуки: java.sun.com/j2ee/sdk_1.3/techdocs/api

Также контейнер может поддерживать разделяемый пул ресурсов, доступных сервлетам, например подключения к БД tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto
Эта фича может заметно поднять производительность - не надо при отработке каждого запроса клиента открывать БД, закрывать БД...

Установим сервлет-контейнер - Tomcat

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

http://tomcat.apache.org/ - The Apache Tomcat Servlet/JSP Container.
Отсюда мы возьмем бинарную сборку для Windows, конкретно отсюда: http://tomcat.apache.org/download-55.cgi версия 5.5.20 Binary Distributions Core Windows service installer. Почти 5 мегабайт.

Ранее я отсюда скачал и установил у себя JRE 1.5 и JDK 1.5 Standard Edition.
У меня это хозяйство расположилось на диске так:
P:\app\Java\jdk1.5.0_09\
P:\app\Java\jre1.5.0_09\
* Запускаем инсталлятор Tomcat: apache-tomcat-5.5.20.exe
* Установка FULL
* Куда ставить: p:\Tomcat5.5 (это будет переменная '''$CATALINA_HOME''' в дальнейшем)
* Порт 8080
* Админский юзер admin
* Админский пароль 123456789
* Ява рантайм оно само нашло в P:\app\Java\jre1.5.0_09
* оставил галки "запустить" и "показать ридми"
Визард почему то сам не закрылся, пришлось давить кнопу "Cancel".

В системе появился сервис Tomcat5, слушающий аж три порта 8009, 8080, 8005.
В трее появилась иконка. По щелчку открывается панель Apache Tomcat Properties.
По адресу http://localhost:8080/ в браузере открывается "поздравительная" страничка:

If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!

И действительно, мы видим результат отработки JSP страницы лежащей в
$CATALINA_HOME/webapps/ROOT/index.jsp

Далее в программе: написание простейшего (но своего!) приложения, в виде сервлета. Как затравку, нам предлагают взять файл
P:\Tomcat5.5\webapps\tomcat-docs\appdev\sample\sample.war
и положить его в
P:\Tomcat5.5\webapps\
а в результате, по адресу http://localhost:8080/sample/ мы увидим предлагаемый нам пример приложения на ява. Этот процесс описан в документации http://localhost:8080/tomcat-docs/appdev/processes.html по ссылке Example App

Установка админской консоли

версия 5.5.20 Binary Distributions - Administration Web Application
скачиваем пакет администрирования, 2.2 мегабайта.
Выдали файл apache-tomcat-5.5.20-admin.zip
распакуем его, в C:\TEMP так, что получается
c:\Temp\apache-tomcat-5.5.20\conf\
c:\Temp\apache-tomcat-5.5.20\server\
и эти два каталога переписываем в (прямо поверх)
P:\Tomcat5.5\conf\
P:\Tomcat5.5\server\
на самом деле файлы из пакета будут просто добавлены в конфигурацию Томкета.
Теперь по адресу http://localhost:8080/admin доступно приложение администрирования.

Конфигурация сервера (каталоги, порты, журналы,...)

Интеграция с веб-сервером Apache HTTPD

Включить поддержку SSL в Tomcat

Реализовать веб-приложение (сервлет)

Здесь я продемонстрирую процесс создания и установки не самого сложного приложения на базе сервлетов.

Нам понадобится инструментарий

* JDK - http://java.sun.com/javase/downloads/index_jdk5.jsp (у меня JDK 1.5), Java Development Kit понятно и без перевода;
* Tomcat + manager (установку этого дела я уже продемонстрировал), сервлет контейнер и средство управления;
* Ant - http://ant.apache.org/bindownload.cgi (у меня версия 1.7 почти 11 мегабайт), автоматизатор процесса разработки, по типу утилиты make, только на яве и для явы.

Я распаковал Ant в каталог, далее называемый ANT_HOME
P:\ant\
так, что получился путь P:\ant\bin\

Перед тем как использовать инструментарий я всегда выполняю команды (иначе работать не будет):
 set PATH=P:\ant\bin;%PATH% 
 set ANT_HOME=P:\ant 
 set JAVA_HOME=P:\app\Java\jdk1.5.0_09 
 set CATALINA_HOME=P:\Tomcat5.5 
Подробности можно узнать здесь: http://ant.apache.org/manual/index.html

Также я выполнил рекомендацию по включению в Ant библиотеки для общения с Tomcat:
COPY P:\Tomcat5.5\server\lib\catalina-ant.jar P:\ant\lib\catalina-ant.jar

Создание приложения

Я создал структуру каталогов для проекта (как рекомендовано в инструкциях к Ant и Tomcat) причем каталог sample может находитьсся где угодно, у меня внутре c:\j\
 md sample\docs 
 md sample\src\mypackage 
 md sample\web\WEB-INF 
 copy build.xml.template sample\build.xml 
этот build.xml - инструкции для Ant, его надо будет отредактировать, шаблон доступен здесь: http://tomcat.apache.org/tomcat-5.5-doc/appdev/build.xml.txt

Создал текстовый файл sample\build.properties (используется Антом)
с содержимым:
app.path=/VDemo1 
catalina.home=P:/Tomcat5.5 
manager.username=admin 
manager.password=123456789 
manager.url=http://localhost:8080/manager 

Tomcat нужны инструкции, что делать с приложением, которое ему подсовывают, для этого - отсюда: http://tomcat.apache.org/tomcat-5.5-doc/appdev/web.xml.txt
взял содержимое (заготовку) для файла deployment descriptor (непременно надо отредактировать) и положил в:
sample\web\WEB-INF\web.xml

Создал файл (исходный код примитивного сервлета):
sample\src\mypackage\VExampleOne.java
с содержимым:
package mypackage; 

import java.io.*; 
import java.text.*; 
import java.util.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class VExampleOne extends HttpServlet { 
 public void doGet ( 
   HttpServletRequest request, 
   HttpServletResponse response) 
  throws IOException, ServletException { 
  String title = "My first app!"; 
  response.setContentType("text/html"); 
  PrintWriter out = response.getWriter(); 

  out.println("<html>"); 
  out.println("<head>"); 
  out.println("<title>" + title + "</title>"); 
  out.println("</head>"); 
  out.println("<body bgcolor=\"white\">"); 
  out.println("<h1>" + title + "</h1>"); 
  out.println("</body>"); 
  out.println("</html>"); 
 } // doGet 
} // VExampleOne class 

Теперь самое время отредактировать содержимое build-файла для Анта:
sample\build.xml
<project name="My first webapp" default="compile" basedir="."> 
  <property file="build.properties"/> 
  <property name="app.name"      value="VDemo1"/> 
  <property name="app.path"      value="/${app.name}"/> 
  <property name="app.version"   value="0.1-dev"/> 
  <property name="build.home"    value="${basedir}/build"/> 
  <property name="catalina.home" value="P:/Tomcat5.5"/> 
  <property name="dist.home"     value="${basedir}/dist"/> 
  <property name="docs.home"     value="${basedir}/docs"/> 
  <property name="manager.url"   value="http://localhost:8080/manager"/> 
  <property name="src.home"      value="${basedir}/src"/> 
  <property name="web.home"      value="${basedir}/web"/> 

  <taskdef name="deploy"   classname="org.apache.catalina.ant.DeployTask"/> 
  <taskdef name="list"     classname="org.apache.catalina.ant.ListTask"/> 
  <taskdef name="reload"   classname="org.apache.catalina.ant.ReloadTask"/> 
  <taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/> 

  <property name="compile.debug"       value="true"/> 
  <property name="compile.deprecation" value="false"/> 
  <property name="compile.optimize"    value="true"/> 

  <path id="compile.classpath"> 
 <pathelement location="${catalina.home}/common/classes"/> 
 <fileset dir="${catalina.home}/common/endorsed"> 
  <include name="*.jar"/> 
 </fileset> 
 <fileset dir="${catalina.home}/common/lib"> 
  <include name="*.jar"/> 
 </fileset> 
 <pathelement location="${catalina.home}/shared/classes"/> 
 <fileset dir="${catalina.home}/shared/lib"> 
  <include name="*.jar"/> 
 </fileset> 
  </path> 

  <target name="all" depends="clean,compile" 
 description="Clean build and dist directories, then compile"/> 

  <target name="clean" 
 description="Delete old build and dist directories"> 
    <delete dir="${build.home}"/> 
    <delete dir="${dist.home}"/> 
  </target> 

  <target name="compile" depends="prepare" 
 description="Compile Java sources"> 
    <mkdir    dir="${build.home}/WEB-INF/classes"/> 
    <javac srcdir="${src.home}" 
          destdir="${build.home}/WEB-INF/classes" 
            debug="${compile.debug}" 
      deprecation="${compile.deprecation}" 
         optimize="${compile.optimize}"> 
        <classpath refid="compile.classpath"/> 
    </javac> 
    <copy  todir="${build.home}/WEB-INF/classes"> 
      <fileset dir="${src.home}" excludes="**/*.java"/> 
    </copy> 
  </target> 

  <target name="dist" depends="compile,javadoc" 
   description="Create binary distribution"> 
    <mkdir   dir="${dist.home}/docs"/> 
    <copy    todir="${dist.home}/docs"> 
      <fileset dir="${docs.home}"/> 
    </copy> 
    <jar jarfile="${dist.home}/${app.name}-${app.version}.war" 
         basedir="${build.home}"/> 
  </target> 

  <target name="install" depends="compile" 
   description="Install application to servlet container"> 
    <deploy url="${manager.url}" 
       username="${manager.username}" 
       password="${manager.password}" 
           path="${app.path}" 
       localWar="file://${build.home}"/> 
  </target> 

  <target name="javadoc" depends="compile" 
   description="Create Javadoc API documentation"> 
    <mkdir          dir="${dist.home}/docs/api"/> 
    <javadoc sourcepath="${src.home}" 
                destdir="${dist.home}/docs/api" 
           packagenames="*"> 
      <classpath refid="compile.classpath"/> 
    </javadoc> 
  </target> 

  <target name="list" 
   description="List installed applications on servlet container"> 
    <list    url="${manager.url}" 
        username="${manager.username}" 
        password="${manager.password}"/> 
  </target> 

  <target name="prepare"> 
    <mkdir  dir="${build.home}"/> 
    <mkdir  dir="${build.home}/WEB-INF"/> 
    <mkdir  dir="${build.home}/WEB-INF/classes"/> 
    <copy todir="${build.home}"> 
      <fileset dir="${web.home}"/> 
    </copy> 
    <mkdir  dir="${build.home}/WEB-INF/lib"/> 
  </target> 

  <target name="reload" depends="compile" 
   description="Reload application on servlet container"> 
    <reload url="${manager.url}" 
       username="${manager.username}" 
       password="${manager.password}" 
           path="${app.path}"/> 
  </target> 

  <target name="remove" 
   description="Remove application on servlet container"> 
    <undeploy url="${manager.url}" 
         username="${manager.username}" 
         password="${manager.password}" 
             path="${app.path}"/> 
  </target> 

</project> 

Теперь редактируем деплоймент дескриптор
sample\web\WEB-INF\web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> 
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
    version="2.4"> 

    <display-name>First VS Java webapp</display-name> 
    <description> Simple example of Java webapp. </description> 

    <servlet> 
        <servlet-name>VDemo1Servlet1</servlet-name> 
        <servlet-class>mypackage.VExampleOne</servlet-class> 
    </servlet> 

    <servlet-mapping> 
        <servlet-name>VDemo1Servlet1</servlet-name> 
        <url-pattern>/servlet1</url-pattern> 
    </servlet-mapping> 
</web-app> 
Выглядит это все кошмарно, но только до тех пор, пока своими руками не сделаешь пару итераций и не осознаешь, что к чему.

Установка приложения в Tomcat

Проверим как компилируется, запустив командный файл такого содержимого:
rem установки переменных я приводить больше не буду, примем "по умолчанию": 
set PATH=P:\ant\bin;%PATH% 
set ANT_HOME=P:\ant 
set JAVA_HOME=P:\app\Java\jdk1.5.0_09 
set CATALINA_HOME =P:\Tomcat5.5 
pushd sample 
start "compile" /wait cmd.exe /k ant all 

У меня все откомпилировалось, теперь проинсталлируем приложение:
pushd sample 
start "remove" /wait cmd.exe /c ant remove 
start "install" /wait cmd.exe /k ant install 

По адресу http://localhost:8080/VDemo1/servlet1
должна появиться страница с текстом
My first app!

Ура, товарищи, оно работает. Вебприложение из одного сервлета. Минимальнее не бывает.

Дальше - самостоятельная работа, я буду копать направления - сервлет генерирует XML а в конце преобразует его в HTML с помощью подготовленных дизайнером XSL файлов; все данные для работы лежат в БД; интеграция с Apache HTTPD. Кстати, простейшие тесты показали увеличение скорости от 5 до 10 раз, по сравнению с кодом на PHP. Я не говорю уже о возможностях кластеризации, встроенных в саму технологию ява контейнеров.

Масштабируем, сервер приложений

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

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

Итого картина у меня сейчас приблизительно такая - вебконтейнер под которым крутятся сервлеты и JSP образует второй уровень, если первым считать пользователя с браузером в руках. Для примитивных случаев этого достаточно. А если не достаточно, добавляем СП (еще говорят сервер J2EE), например контейнер EJB. Получаем третий уровень, на который высаживаем тяжелый компутинг. Причем СП создается обычно таким образом, чтобы его можно было посадить на кластер или ферму.

Терминология, понятия

Редакции Java, варианты платформы
Существует три основных редакции языка и базовых библиотек:
* j2SE - Java 2 Standard Edition
* J2EE - Java 2 Enterprise Edition
* J2ME - Java 2 Micro Edition
Микроедишн - это для портативных, мелких устройств. Например, в мобильных телефонах живет именно J2ME. Стандард - это базовый набор средств "просто для разработки и запуска просто ява программ". А нас как разработчиков неслабых веб проектов, интересует в основном энтерпрайз едишн. Там масса дополнительных библиотек, спецификаций и средств для поддержки распределенных масштабируемых управляемых ява систем.

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

XML - eXtensible Markup Language
Наиболее важный и общеупотребимый формат данных, язык и средство для соединения подсистем в мире корпоративных (и не только) проектов. Применяйте хмл где можно и нельзя - все будут думать что вы крутой.

Servlet, сервлеты
Ява программы, исполняемые на сервере, если искать аналогии, то ближе всего к сервлетам будут CGI программы для веб сервера. Сервлеты могут динамически генерировать вебстраницы отправляемые клиентам в ответ на запросы.
Сервлеты эффективны при разработке веб приложений, в которых идет работа с БД, динамически генерируется содержимое, отображаемое браузерами, сохраняется уникальная для каждого клиента информация о сеансе.
Сервлеты обычно являются потоками одного процесса в виртуальнй машине ява.

JSP - Java Server Pages
Опять же, по аналогии - ближе всего PHP или ASP страницы веб сервера. Задачи почти такие же как и у сервлетов, только удобнее ваять дизайн, применяя JSP. В конечном итоге, JSP все равно компилирются в сервлеты. Сами страницы содержат
Скриптлеты - Scriptlet
исходный код коротких подпрограмм на языке Java. Эти скриптлеты обычно используют для выполнения работы некие компоненты -
JavaBeans - бины
Самостоятельные классы ява, построенные в соответствии с компонентной моделью Java.

TagLib - Tag Library
Ява библиотеки для использования в JSP. Позволяют простым использованием специальных тегов в странице добиться богатой функциональности. Дают возможность веб-дизайнерам добавлять динамическое содержание без программирования.

JSTL - JSP Standard Tag Library
Стандартный набор библиотек TagLib.

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

SOAP - Simple Object Access Protocol
протокол на базе XML, по этому протоколу можно использовать веб-сервисы.

EJB - Enterprise JavaBeans
Компонентная модель ява, применяется для построения бизнес логики корпоративных приложений. Содержит сеансовые компоненты (с состоянием и без), поддержку распределенных транзакций, компоненты управления данными (компоненты-сущности) для управления сущностями хранимыми в БД. Дает возможность строить надежные и устойчивые многоуровневые приложения. Используя RMI и контейнеры EJB, компоненты способствуют распределению логики по разным узлам сети.
И многое другое...

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

JMS - Java Message Service
Технология использования в ява средств промежуточного (middleware) ПО ориентированного на работу с сообщениями. Коммуникации путем обмена сообщениями, в двух моделях "точка-точка" или "издатель-подписчик". В EJB есть компоненты управляемые сообщениями.

Tomcat Client Deployer (TCD)
Инструмент для установки веб-приложения в сервлет-контейнер Tomcat. Утилита командной строки.

Коллекция ссылок по теме


Ветер

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

Гидрокостюм это вещь! 3-мм неопрен позволяет без содрогания купаться в воде холоднее 20 по Цельсию (сегодня водичка была градусов 18). И на ветру совсем не холодно, хотя температура воздуха была 15-16 градусов.

А еще я сегодня осознал, что с парусом я управляюсь неправильно. Сразу после этого попробовал как надо и поразился, насколько меньше сил уходит на удерживание паруса и передачу тяги в доску.
Раньше брал паруса небольшие, до 6 метров. С ними, при моих массогабаритах, что правильно, что неправильно — разница небольшая. Не чувствуется. А взял 7-ми метровый и сразу ощутил — тяжело. Просто реально тяжело парус ворочать. Тут все ошибки парусения и проявились.
Буду исправлять.

2012-07-18

Почта

Почта России «доставляет».
Один из заказанных мокрых костюмов за пять дней дошел из (даже не знаю — из откуда точно) Британии до нашей таможни. На таможню ушли сутки. А потом бандеролька гуляла десять! дней по Москве.
И это в то время, как наладился ветер и похолодало. Надо бежать катацца, а костюмчик у почтарей. Это не Почта России, это Позор России.

Когда уже глаз саурона обратится на это безобразие и ручное управление подкрутит сюрикены в жопах ответственных?

2012-07-17

XML

Удобно и эффективно генерировать код на XML можно так:
    >>> from StringIO import StringIO
    >>> out = StringIO()
    >>> xml = XmlWriter(out)
    >>> xml.addNamespace("xhtml", "http://www.w3.org/1999/xhtml")
    >>> xml.startTag("xhtml:html")
    >>> xml.startTag("xhtml:body")
    >>> xml.text("Hello world!")
    >>> xml.tag("xhtml:img", {"src": "smile.png", "alt": ":-)"})
    >>> xml.endTag()
    >>> xml.endTag()
    >>> xml.close()
    >>> print out.getvalue().rstrip("\r\n")
    
    <?xml version="1.0" encoding="utf-8"?>
    <xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml">
      <xhtml:body>
        Hello world!
        <xhtml:img alt=":-)" src="smile.png" />
      </xhtml:body>
    </xhtml:html>


А я в свое время подобный велосипед сам сделал, на PHP. У нас страницы сайта выдавались на XML и потом уже превращались в HTML накладыванием епитимьи шаблонов XSL.
Интересно, много ли нынче сайтов на XML-е работает?

2012-07-16

Покатушки

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

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

2012-07-15

Кроссплатформность

Такой вот простой эволюционный механизм — конкуренты отмежевываются друг от друга

Честно говоря, меня, как программиста, нынешняя картина разработки под мобильные платформы несказанно печалит. Ключевые игроки на этом рынке -- Apple, Google, Microsoft -- прикладывают все силы, чтобы разыграть перед ошалевшими девелоперами сцену по легендарной крыловской басне о сбежавших из зоопарка лебеде, раке и щуке.

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

В случае Microsoft ситуация вообще складывается парадоксальная.
Если бы они смогли обеспечить компиляцию C/C++ кода для своей платформы и поддержали бы OpenGL ES, то огромное число проектов было бы портировано под WP7 просто потому, что это было бы очень не сложно сделать. А так -- с одной стороны сделано все, чтобы перенос приложения для своей платформы превращался в тихий ужас, а с другой, тратятся огромные бюджеты на то, чтобы заинтересовать создателей успешных проектов в перенос их детищ на "молодую, но перспективную" платформу.


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

И программистам хорошо — никто без работы не останется.

Ну и что, что неэффективно? Эволюция вообще очень неэффективна, с точки зрения энергозатрат.

2012-07-14

Magic

Тяжело вечером тяпницы переваривать эдакие материи. Но ведь интересно

Вдохновлённый недавним постом про текучие интерфейсы на PHP, я сразу задумался как можно реализовать подобное на питоне проще и красивее (на питоне всегда всё проще и красивее). Предлагаю несколько способов в порядке поступления мыслей.
...
Теперь мы обработаем все методы сразу, но будем проверять модификацию и создание методов для того чтобы и их обернуть.
class NewMetaChain(type):
    def __new__(cls,name,bases,dict):
        old = dict.get('__setattr__',object.__setattr__)
        def wrap(fn,inst=None):
            def new(*args,**kwargs):
                ans = fn(*args,**kwargs)
                return ans if ans!=None else inst or args[0]
            return new
        special = dir(cls)
        for item, fn in dict.items():
            if item not in special and isinstance(fn,FunctionType):
                dict[item] = wrap(fn)
        def new_setattr(inst,item,val):
            if isinstance(val,FunctionType):
                val = wrap(val,inst)
            return old(inst,item,val)
        dict['__setattr__'] = new_setattr
        return type.__new__(cls,name,bases,dict)

class UsefulClass4():
    __metaclass__ = NewMetaChain
    def __setattr__(self,item,val):
        if val == 172: val = "giza"
        object.__setattr__(self, item, val)
    val = 1
    def add(self,val): self.val += val
    def mul(self,val): self.val *= val
    def nul(self): pass

Помимо того что мы теперь при каждом вызове не оборачиваем методы (что дало ~30% прироста в скорости), мы ещё проводим необходимые проверки не на каждом считывании полей объекта, а на каждой записи (что происходит реже). Если запись отсутствует — работает так же быстро как и способ с декораторами.


Как справедливо заметили в каментах

zw0rk 10 ноября 2011 в 19:42
Метод с дек@ратором гораздо лучше, потому что explicit is better than implicit. Имхо.

Grundiss 10 ноября 2011 в 21:10
Тоже считаю, что лучше уж написать 10 «собачек», чем портить себе карму отзывами будущих поколений.

just_wow 11 ноября 2011 в 09:41
Раз уж речь зашла о Python-way, то не лучше ли будет просто дописать «return self» в конце каждой функции? Цена тому — все таже одна строка кода, зато простоту понимания сторонним читателем повысит неимоверно, нежели декоратор.

zw0rk 11 ноября 2011 в 13:16
Лучше конечно, но не так «илитарно» :)

2012-07-13

Snow Crash

Слушаю сейчас аудиокнигу - «Snow Crash» пера Neal Stephenson. Читает Jonathan Davis, не тот, который рок-музыкант, другой.

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

Хотел бы я, чтобы все аудиокниги были зачитаны такими мастерами. Уже немало русскоязычных аудиокниг переслушал — ничего подобного такому качеству пока не встретил.

2012-07-11

Time

Андрей Светлов на линии:

Речь пойдет о функциях для измерения интервалов времени, расположенных в модуле time.
time() и clock()
Очень долго их было ровно две: time.time() и time.clock().
Использование предельно простое:
t1 = time.time()
# do tested stuff
print(time.time() - t1)
Получаем время выполнения кода в секундах.
Две функции нужны для того, чтобы усложнить жизнь программиста. Дело в том, что на Windows точнее работает функция time.clock, а на прочих Unix/Linux — time.time
Прогресс не стоит на месте, и появились функции c наносекундным разрешением: time.clock_gettime и time.clock_getres являются тонкими обёртками над одноимёнными Posix вызовами
Не вполне ясно, какой тип таймера выбирать.
...
Во первых, возвращаемое время может быть абсолютным и относительным. Если по абсолютному времени можно узнать «который час», то относительное годится лишь для измерения интервалов
Обычно желание простое: измерить интервал времени с максимально возможной точностью, причём способ не должен зависеть от установленной операционной системы и используемого «железа».

Вот тут и приходят на помощь функции time.monotonic() и time.wallclock(). Они не требуют параметров, работают везде и используют максимально точный из доступных таймеров. Для Windows это clock(), на Linux последовательно перебираются CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC и CLOCK_REALTIME. Кто первый отзовётся — тот и лучший.

Разница между функциями незначительная: time.wallclock() попытается перейти к таймеру абсолютного времени если не найдет лучший вариант (и никогда не закончится исключением), time.monotonic() выбросит OSError


Подробно и внятно изложено, прекрасная статья и, к счастью, не последняя.

Про тайны импорта в Python.

2012-07-10

Pyquery

Забавно, гугель, будучи спрошен про pyquery, активно отвечает про jQuery. И в чем-то он прав.

pyquery allows you to make jquery queries on xml documents. The API is as much as possible the similar to jquery. pyquery uses lxml for fast xml and html manipulation.


Народ активно пользуется для парсинга сайтов. Даже в Grab встроен pyquery как составная часть.

Полезняшка, однозначно.

BinaryString

Забавно, только я собрался отправить кусок файла из браузера яваскриптом на сервер, как тут же выяснилось, что в яваскрипт (браузерном, во всяком случае) нет подходящего типа данных. Всего-то надо что-то вроде ByteArray произвольного размера.
При этом кое-что есть. Есть строки, есть блобы (не у всех, но есть) и прочие хитрости. Не говоря уже о том, что буквально на днях я прекрасно засылал яваскриптом бинарные куски файлов на сервер, который, на минуточку, крутится на яваскриптовом движке!

Придется химичить. А всего-то хотел вернуть из сильверлайтного плагина массив байт и отправить его яваскриптом под видом multipart/form-data, Content-Transfer-Encoding : binary.
Кстати, из упомянутого плагина в яваскрипт возвращается тип данных byte[], без вопросов. Но вот в яваскрипт это выглядит как 'System.Byte[]' и пока неясно, что с ним можно сделать, кроме того как взять значение атрибута length.

Вопросов больше чем ответов.

2012-07-09

reStructuredText

Полезная штука, текстовый редактор ReText (тоже на Python-е)

Основные возможности ReText:
Полная поддержка Markdown и ReST, а также расширений Markdown;
Поддержка вкладок и двухпанельного редактирования ("Live Preview");
Экспорт в форматы HTML, PDF и ODT;
Встроенный генератор веб-страниц;
Загрузка файлов в Google Docs;
Возможность автоматического сохранения файлов;
Поддержка CSS-стилей;
Подсветка синтаксиса;
Быстрая вставка тегов и символов HTML


Лично мне особенно пригодится «встроенный генератор веб страниц». Да и вообще, легче набивать текст, когда в Preview сразу видно, что получается.

2012-07-08

Муки выбора

Иногда, когда нет явного фаворита, сделать выбор очень непросто.
Вот, к примеру, отели на Коста Брава, Испания. Рядом с Санта Сусанна. Хочется, чтобы отель был не менее 4-х звезд, на самом берегу — прыг из отеля, и ты уже на пляже. Хочется, чтобы «все включено», чтобы жрать и пить не задумываясь о бюджете. Хочется, чтобы у отеля была пристойная территория, чтобы можно было в тенечке в шезлонге поваляться. Хочется, чтобы еда была вкусной и разнообразной, ресторан чистым а номера удобными. А нету.

Вот чтобы все и сразу — нету. Или отель на пляже и все включено, или хороший ресторан и приличные номера. Вот и выбирай :) А пристойной территории вообще ни у кого нет. Выбираем из того, что есть.

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

На пляже, но все остальное на 3 (из 5) или на 3+

На пляже и, в целом, хороший, для 3-х звезд, относительно недорого

На пляже, популярный, на 4 балла (из 5) или 4-
Вот в него и заселимся. Потому как близость к морю и all inclusive на семейном совете были признаны более значимыми, чем роскошность отеля.

Что-то испанцы не впечатлили пока.

2012-07-06

Прекрасная простота

The motto of InDefero is "beautiful simplicity".
Сам сайт, кстати, сделан на InDefero, что позволяет заценить решение не отходя от кассы.

Мой словарик дает такое определение
simplicity
n
1) простота;
2) незатейливость;
3) бесхитростность, простодушие;
4) туповатость


Определение InDefero от Опеннет:

Вышла новая версия системы для организации управления разработкой программных проектов Indefero, являющаяся клоном GoogleCode и поддерживающая работу с системами управления исходными текстами Git, Mercurial, Subversion и Monotone. Код проекта распространяется в рамках лицензии GPL


Реально незатейливая система, заметно проще чем trac. Но для начала (надо же когда-то начинать управлять разработкой софта) самое оно.

2012-07-04

Жизнь UPS-а

Тепло, даже жарко. Повышенная влажность. То фотокамера в коммуникаторе сдохнет, то батареи в UPS.

Сегодня, 3 июля 2012 года, вероломно и без обьявления войны, у нас сдох ИБП (Powercom IMD-1025AP). В смысле, батареи не держат. Ну это я так думаю, во всяком случае.
Двух лет не прошло с момента замены батарей.

Слабоваты оказались те батареи Gembird. Оригинальные Yuasa держались дольше, около трех лет. На этот раз заказал их, Yuasa NPW36-12, две штуки. Теперь это дешевле чем Gembird.

Хотел купить в Юлмарте, ибо удобно (с карточки можно оплатить, безналом) и дешевле, да и бонусы у меня там, но нет, не вышло — при оформлении заказа мне намекнули, что доставки не будет, только самому забирать из двух конкретных магазинов. На нет и суда нет, нуихусим, не Юлмартом единым живы. Купил (опять!) в Джасте. 690 рублей за штуку плюс 290 за доставку. Ночером заказал, вечером привезли.

Любопытно, сколько эти аккумы проживут.

Да, это реклама Джаста :)

2012-07-03

Product vs Framework

Мне нравится Plone, он хороший. Да и привык я к нему. Но это не мешает поглядывать по сторонам в поисках альтернатив. Например, Django. Или Pyramid.
Но есть засада, эти вещи нельзя сравнивать по простому. Plone надо сравнивать не с Django а с Django CMS. Ибо Plone — это продукт, а Django это фреймворк. Продукт для пользователей, фреймворк — для разработчиков.

Слайд 44


Занятное слайд-шоу. Рассказывает о пользе точного позиционирования изделия. Там и про Pyramid есть цитата. В более развернутом виде такая:

And then it happened: After I delivered the first app, things got very silent. I stopped getting calls, no more emails, not even a single postcard! ... until I realized: the team didn't need me anymore. Python and Pyramid were too damn easy! My days as a consultant would soon be counted. :-)
Lessons learned
* Don't teach Pyramid, you'll become useless soon
* Instead recommend hard-to-learn frameworks, or better yet, vendor-tied and hard-to-install black boxes
* Find a new job quick before more people find out about Pyramid


Хотя, что толку читать эти обзоры. Пока сам не попробуешь какой-нибудь проект сделать на альтернативной платформе, все рассуждения будут напоминать «я Пастернака не читал, но осуждаю».

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) Java (22) humor (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Manager (15) web-browser (15) Никонов (15) Klaipeda (14) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) serialization (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)