воскресенье, 2 ноября 2008 г.

MS SQL Server

Понадобилось скачать сабж. Буду учить брата переводить 1С 7.7 на SQL. Нашёл на оф. сайте:
Microsoft SQL Server 2005 Express Edition
Microsoft SQL Server Management Studio Express

Експресс версия имеет ограничение на 1 процессор и размер базы в 4Гб. А так - ничего, вполне функциональная.

четверг, 30 октября 2008 г.

HP 530 - dvd привод работает в PIO-mode

В настройках IDE установлено "DMA если доступно", но привод упорно отказывался повиноватся и работал только в PIO. В результате запись диска занимала около часа и одно ядро поцессора и паралельно что-либо делать на ноутбуке было "некомфортно".

Гугление на тему обновления драйверов или прошивки не дало результата. Вся проблемма оказалась в настройках реестра.

Открываем HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96A-E325-11CE-BFC1-08002BE10318}\000x

В подветках есть параметры MasterIdDataChecksum и SlaveIdDataChecksum. Удаляем их и перезагружаемся.

пятница, 17 октября 2008 г.

Установка SMTP сервера на Ubuntu

Установить мейл-сервер проще простого. Соединяемся по SSH (например, с помощью Putty) и:

sudo apt-get install postfix
Возможно понадобится ключ --fix-missing

Программа установки попросит установить несколько параметров. Вниматено читаем тексты с подсказками и конфигурируем.

Затем:
sudo dpkg-reconfigure postfix

И релоад: /etc/init.d/postfix reload

И всё. У вас есть свой SMTP сервер :)

четверг, 16 октября 2008 г.

Вы заметили баннер справа?

Прочитал сегодня на Хабре заметку о фонде "Подари жизнь!" и не просто смог не добавить их баннер на свои стартапы и блоги. Потратил 10 минут, а может так статься, кому-то это спасет жизнь. У наших давних друзей в понедельник умерла девочка. 22 года, как говорится жить да жить. Маленька дочурка осталась без мамы.

Не будьте чёрствыми. Будьте людьми.

вторник, 12 августа 2008 г.

Готовлю голый Ubuntu сервер для Django проекта

Итак, у меня в руках голый девелопмент сервер на Ubuntu. Задача: настроить сервер для проекта на Django framework.

Процесс установки всего добра (по редакции гугля плюс немного отсебятины):

sudo apt-get install python
sudo apt-get install subversion
sudo apt-get install mysql-server
sudo apt-get install python-mysqldb
sudo apt-get install python-imaging
sudo apt-get install libapache2-mod-python

/etc/init.d/apache2 restart

Открываю вкладочку Фаерфокса по адресу сервера и...

It works!

Идем дальше:

sudo apt-get install phpmyadmin

http://адреснашегосервера/phpmyadmin

Django берем с svn, временно сохраняем в какую-то папочку:
svn co http://code.djangoproject.com/svn/django/trunk/
Затем из trunk - python setup.py install
Установщик скопирует фреймворк в папку пакетов Питона.

красота :)

воскресенье, 10 августа 2008 г.

Обновляемся

Плавно перехожу на транковую версию Django. Предыдущие проекты писал на 0.96, и, как оказалось сильно отстал от жизни.

Например, официальная версия django-tagging 0.2.1 не работает с транком Django :) Нужно использовать svn версию: http://django-tagging.googlecode.com/svn/trunk/

Или вот еще, при импорте теперь нужно писать полный путь, включая имя проекта. т.е.
from appname.models import *

не прокатит, нужно писать
from projectname.appname.models import *

Иначе может произойти двойной импорт. Всё бы ничего, но в случае двойного импорта newforms админка матюкнётся AlreadyRegistered и валидация не пройдет.

четверг, 19 июня 2008 г.

Популярные AJAX библиотеки теперь можно загружать с сервера Google

Google Code начал хостить популярные библиотеки JavaScript - JQuery, Prototype и другие.

А знаете, что это значит? Можно указать в своей странице загружать эти .js с сервера Google. И библиотеки будут загружатся пользовательским браузером всего один раз, независимо от количества посещаемых сайтов.

http://code.google.com/apis/ajaxlibs/

Утянуто у rossp

понедельник, 2 июня 2008 г.

Установка Text Link Ads на Python-сайте

Решил использовать сервис Text Link Ads для продажи ссылок с одного своего англоязычного сервиса (PR страниц 3-4). И столкнулся с тем, что для сайта на платформе Python/Django они не предлагают готового Ad-кода.

Гугление не дало результата и я включил моск.

Для сайтов на платформе Blogger они предлагают размещать RSS-поток с ссылками. Почему бы не использовать и мне такой вариант, подумал я. Все просто - берем RSS-гаджет и подключаем его к своему TLA-аккаунту.

Мне приглянулся "Simple rss reader" из гаджетов Google. Простотой в настройке и установке.

Что получилось, можно посмотреть на Getting tasks done

четверг, 29 мая 2008 г.

Игра ФИДО 2.0 - античитерское обновление #1

Не так давно я запустил на Хабре весть об игре Фидо 2. Вполне ожидаемая реакция - за два часа сервер лёг. Но вот чего я не ожидал (да, наивный, верю в человеческую честность), так это такого количества читерских запросов. Они то и положили веб-приложение.

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

Вот так-то.
Исходники в помощь: http://code.google.com/p/fido2/

понедельник, 26 мая 2008 г.

Django и Google App Engine: шаблоны и статические файлы

В предыдущем посте было рассказано, как создать простейший проект на GAE + Django. Сейчас давайте попробуем подключить к проекту шаблоны Django и поддержку статических файлов - таблиц стилей, скриптов и картинок.

Наш Django проект будет называтся dvk, и содержать приложение main. В папке приложения создаем каталог для шаблонов templates:
dvk/
main.py
app.yaml
    dvk/
    manage.py
    settings.py
    urls.py
      main/
      __init__.py
      models.py
      views.py
        templates/


Чтобы среда знала, где искать файлы шаблонов, нужно прописать путь в файле настроек проекта settings.py
import os
ROOT_PATH = os.path.dirname(__file__)

TEMPLATE_DIRS = (
  ROOT_PATH + "/main/templates",
)


Теперь можно создать файл шаблона main.html в папке шаблонов. Наш шаблон не будет делать ничего сверх полезного :) Просто скажем браузеру "Hello world!"
Hello world!


Для вывода страницы создадим процедуру-контроллер в файле views.py и привяжем её к обработке запроса главной страницы сайта в urls.py
#dvk/dvk/main/views.py
from django.shortcuts import render_to_response

def index(request):
  return render_to_response("main.html")


#dvk/dvk/urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns("",
  (r"^$", "dvk.main.views.index"),
)


Теперь можно протестировать наше приложение - dev_appserver.py dvk
Откройте браузер с адресом http://127.0.0.1:8080/ и у вас отобразится "Hello world!" :-)

Чтобы Google App Engine обрабатывал статические файлы, нужно в файле настроек GAE приложения включить в секцию handlers параметр static_dir:
application: dvk
version: 1
runtime: python
api_version: 1

...

handlers:
- url: /static
static_dir: static

...


Параметр url указывает, по какому адресу будут доступны файлы, а значение параметра static_dir - имя и расположение папки. В нашем примере она располагается в корне проекта и имеет имя static. Теперь в шаблонах можно обращаться к статическим файлам, например для загрузки таблицы стилей: link href="/static/main.css" type="text/css" rel="stylesheet"

Использованные материалы:
Django on Google App Engine: Templates and static files
Configuring an App

пятница, 9 мая 2008 г.

Django приложение на Google App Engine в 12 шагов

В этом туториале рассказывается, как создать простое Django приложение с использованием Google App Engine. Предполагается, что у вас уже есть аккаунт в Google App Engine.

1. Для начала нужно зарегистрировать имя приложения в GAE и установить у себя тулкит. Среда Google App Engine работает только с Python 2.5 (2.5.1, 2.5.2). Вместе с Питоном должен быть установлен и Django 0.96 (0.96.1) (.../python/libsite-packages/django).

2. Создайте папку для вашего приложения. Имя и размещение не имеет значения. У меня папка называется "dvk".

3. В папке приложения создайте файл main.py
import os, sys

os.environ["DJANGO_SETTINGS_MODULE"] = "dvk.settings"

ROOT_PATH = os.path.dirname(__file__)
sys.path.append(ROOT_PATH)

# Google App Engine imports.
from google.appengine.ext.webapp import util

# Force Django to reload its settings.
from django.conf import settings

settings._target = None

import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher

# Unregister the rollback event handler.
django.dispatch.dispatcher.disconnect(
django.db._rollback_on_exception,
django.core.signals.got_request_exception)

def main():
    # Create a Django application for WSGI.
    application = django.core.handlers.wsgi.WSGIHandler()

    # Run the WSGI CGI handler with that application.
    util.run_wsgi_app(application)

if __name__ == "__main__":
    main()

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

4. Создайте файл app.yaml
application: dvk
version: 1
runtime: python
api_version: 1

handlers:
- url: /static
static_dir: static

- url: /.*
script: main.py

Имя приложения естественно подставьте по своему вкусу :)

5. Из папки приложения выполните команду создания нового Django-проекта:
django-admin.py startproject dvk

Маленькое замечание: Всего у нас будет 2 папки проектов - папка GAE-проекта и папка Django-проекта внутри неё. Внешний проект выполняет роль обёртки.
dvk/
main.py
app.yaml
    dvk/
    manage.py
    settings.py
    urls.py

В файле настроек Django-проекта settings.py нужно удалить всё, что относиться к настройкам БД, админке, аутентификации и сессиям. Google App Engine не поддерживает модели Django, поэтому эти модули работать не будут.

6. Теперь можно протестировать наше GAE+Django приложение
cd ..
dev_appserver.py dvk

INFO 2008-04-08 19:08:10,023 appcfg.py] Checking for updates to the SDK.
INFO 2008-04-08 19:08:10,384 appcfg.py] The SDK is up to date.
INFO 2008-04-08 19:08:10,404 dev_appserver_main.py] Running application dvk on port 8080: http://localhost:8080

Откройте браузер с адресом http://127.0.0.1:8080/ и у вас отобразится стандартная страница Django с сообщением It worked!

7. Создайте Django апликейшн в папке Django-проекта.
manage.py startapp main


8. Теперь самое время добавить модель данных. Мы создадим простой класс Visitor, который будет хранить информацию обо всех посетителях сайта.
#.../dvk/dvk/main/models.py
from google.appengine.ext import db

class Visitor(db.Model):
    ip = db.StringProperty()
    added_on = db.DateTimeProperty(auto_now_add=True)

При добавлении или изменении моделей в Google App Engine не требуется проводить синхронизацию с базой данных. Она выполняется автоматически.

9. Теперь создадим процедуру-контроллер. Она будет записывать в базу данных параметры посетителя нашей веб-страницы и отображать список всех посетителей.
#.../dvk/dvk/main/views.py
from django.http import HttpResponse
from dvk.main.models import Visitor

def main(request):
    visitor = Visitor()
    visitor.ip = request.META["REMOTE_ADDR"]
    visitor.put()
    result = ""

    visitors = Visitor.all()
    visitors.order("-added_on")
    for visitor in visitors:
        result += visitor.ip + u" visited on " + unicode(visitor.added_on) + u""

    return HttpResponse(result)


10. В файле диспетчера URL-ов укажем, что наша процедура ответственна за обработку запроса главной страницы сайта.
#.../dvk/dvk/main/urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns("",
(r"^$", "mashname.main.views.main"),
)

11. Протестируйте своё приложение открыв окно браузера по адресу http://127.0.0.1:8080/. При каждом обновлении веб-страницы будет добавлятся новая строка и соответственно новый объект Visitor будет записан в БД. GAE также автоматически создает админ-панель приложения - http://127.0.0.1:8080/_ah/admin/

12. Теперь можно заливать наше приложение на GAE: appcfg.py update dvk
При первом выполнении команда попросит авторизироваться.

Использованные материалы:
Running Django on Google App Engine
Django on Google App Engine in 13 simple steps

__________________________________
Мои переводы:
Начинайте бизнес создавая стартап
Интервью Пола Грэма для Found|READ
Как выглядит рабочее место в XXI веке

среда, 16 апреля 2008 г.

Перевод статьи Web Worker Tip: Don’t Go Dark

Перевёл еще одну интересную статью с Web Worker Daily

Не уходи в тень, будь на виду!

Большое преимущество независимой работы это возможность находиться в окружении, которое нравиться – в домашнем офисе, интернет-кафе, или коворкинг центре. Хоть даже в парке, лишь бы Wi-Fi тянул. И совсем необязательно постоянно быть в офисе заказчика.

Но это палка о двух концах: вы можете заплатить за свою свободу уходом в категорию "ни слуху, ни духу". Заказчикам очень важно получать от вас сигналы...

среда, 9 апреля 2008 г.

Перевел 2 статьи с Web Worker Daily

Альтернативы домашнему офису

Есть некая ирония в том, что-бы быть веб-работником и проводить в домашнем офисе большую часть времени.

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

Если у вас появилось желание покинуть привычное рабочеее пространство, вот несколько альтернатив...


7 советов как повысить продуктивность работы с Firefox

Для многих из нас Firefox это браузер, в котором мы проводим большую часть дня. Эти советы помогут сделать более эффективной работу в Firefox...

Полный перевод читайте на Стартаперах в разделе "Инструменты бедуина".

Анализ страницы на плотность ключевых слов

Нашел для себя неплохую онлайн-тулзу для анализа страницы на плотность слов - http://vface.controlstyle.ru/ns.php
Умеет различать различные словоформы, что очень приятно. Паралельно умеет оценивать "тошноту" страницы :)
Сейчас буду мучить страницы Стартаперов.Ру :)

четверг, 3 апреля 2008 г.

Фиолетовая корова

Вчера по совету в блоге Сета Година искал на Фликере картинку с фиолетовой коровой для проекта Стартаперы.РУ
С фиолетовыми коровами было туго, поэтому решил изменить цвет на пурпурный. Все равно в Фотошопе всё можно исправить :)))
Нашел вот такую забавную буренку:
Фотограф: adiything

Фоновая загрузка файлов на сервер

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

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

Реализация

После загрузки страницы запускается периодический вызов функции LoadLogotype()


<script type="'text/javascript'" src="'/appmedia/jquery.js'"></script>

<script language="JavaScript" type="text/javascript">
var previous_logo = "";

//-----------------------------------------------------------------------------
function LoadLogotype() {
var card_logo = $("#card_logo").val();

if ((card_logo != "") && (previous_logo != card_logo)) {
previous_logo = card_logo;
document.getElementById("uploadphoto").submit();
}
}
//-----------------------------------------------------------------------------
$(function() {
setInterval("LoadLogotype()", 1000);
});
</script>

Функция LoadLogotype() проверяет, выбран или изменился ли файл логотипа и, если это так, то отправляет форму "uploadphoto" на сервер.

Форма имеет параметр target="upload_frame", то-есть она не будет инициировать переход на другую страницу. Все изменения будут касаться только скрытого фрейма. После отправки формы в этом фрейме загрузиться отданный сервером результат.



<form id="uploadphoto" target="upload_frame" enctype="multipart/form-data" action="/upload_logo/" method = "post">
Логотип: <input id="card_logo" name="card_logo" type="file">
</form>



<iframe id="upload_frame" name="upload_frame" style="display:none">



Серверная функция обработки загрузки логотипа сохраняет файл в папке пользователя. Также загружаемый файл проверяется по списку alloved_files – защита от загрузки пользователем неразрешенных файлов.
Как результат функция отдает URL к файлу.

#------------------------------------------------------------------------------
def upload_logo(request):
'Handles upload of logo images'

alloved_files = ('.jpg', '.jpeg', '.png', '.gif')

id = request.session['our_id']
path = settings.MEDIA_ROOT + 'uploads/%s/' % id

if not os.path.isdir(path):
try:
os.makedirs(path)
except:
return "Error: could not create directory to upload files!"

for image_file in request.FILES:
filename = request.FILES[image_file]['filename']
name, ext = os.path.splitext(filename)
if ext not in alloved_files:
continue

if filename == '':
continue

content = request.FILES[image_file]['content']

f = open(path + filename, 'wb')
try:
f.write(content)
finally:
f.close()

content = {
"image": "/appmedia/uploads/%s/%s" % (id, filename),
}

return render_to_response("done.html", content, context_instance=RequestContext(request))

Результат рендеринга шаблона done.html попадет в невидимый IFRAME "upload_frame". Скрипт находит в родительском документе элемент "card_logotype" и заменяет URL картинки на отданный сервером.


<html>
<head>
<script language="JavaScript" type="text/javascript">
parent.document.getElementById('card_logotype').src="{{image}}"
</script>
</head>
<body>
</body>
</html>


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

Посмотреть как это работает, можно здесь: http://bicards.pythondevside.com/
Кросс-пост в Хабрахабр

среда, 2 апреля 2008 г.

Настойчивость

Быть настойчивым не значит использовать одну и ту же тактику для достижения цели снова и снова. Это утомляет.
Настойчивость - это двигаться к одной и той же цели.

Оригинал: Persistence

Где искать отличные, захватывающие фото

Если вам нужны фотографии для презентации, сайта или брошюры - попробуйте поискать на Фликере (Flickr).
Откройте расширенный поиск, установите флажок "Искать только фотографии с Creative Commons-лицензией" и ищите на здоровье. Этот тип лицензий позволяет свободно использовать фотографии в ваших работах. Такой себе подарок фотографов вам.

Уперто с: http://sethgodin.typepad.com/seths_blog/2008/03/where-to-find-g.html

вторник, 1 апреля 2008 г.

Внешний вид TinyMCE

В проектах в качестве WYSIWYG редактора я пользуюсь TiniMCE. Аргументация ? Просто нравиться он мне и всё тут :)

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

Вот конфигурация TinyMCE, которая прижилась у меня:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
theme_advanced_buttons1 : "bold,italic,underline,separator,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
extended_valid_elements : "a[namehreftargettitleonclick],img[classsrcborder=0alttitlehspacevspacewidthheightalignonmouseoveronmouseoutname],hr[classwidthsizenoshade],font[facesizecolorstyle],span[classalignstyle]"
});

Перевод DjangoBook

Руслан Попов сделал практически полный перевод DjangoBook на русский язык.
Перевод постоянно дополняеться.
Ссылка: http://cargo.caml.ru/djangobook

Поисковый системы + сайт

Решил сделать заметку для себя, что-бы не гуглить постоянно.


Добавить URL - Яндех

http://webmaster.yandex.ru/

Включить свой URL в Google
http://www.google.com/addurl/

Поисковик Yahoo
http://search.yahoo.com/info/submit.html

Статистика запросов - Яндех
http://wordstat.yandex.ru/

10 принципов хорошего дизайна - Дитер Рамс

Дитер Рамс - промдизайнер компании Braun в 50-х - 60-х годах. Его работы вдохновляют дизайнеров Apple по сей день.

Стремление к простоте и честности дизайна всегда декларировалось Рамсом и сформулировано в его 10-ти принципах хорошего дизайна:

  1. Хороший дизайн инновационен
  2. Хороший дизайн делает продукт удобным
  3. Хороший дизайн эстетичен
  4. Хороший дизайн помогает понять продукт
  5. Хороший дизайн ненавязчив
  6. Хороший дизайн честен
  7. Хороший дизайн надежен
  8. Хороший дизайн проработан до последней детали
  9. Хороший дизайн не конфликтует со средой
  10. Хороший дизайн это как можно меньше дизайна

Подробнее о Дитере Рамсе и его работах.

понедельник, 10 марта 2008 г.

Облако тэгов - Django tagging для Django 0.96 #2

Продолжение возни с тэгами.

Django-tagging 0.2.1 я не похачил, а наоборот - взял всё самое лучшее из него и перенёс в версию 0.1. Таким образом получилось совместимое с Django 0.96 приложение с готовыми инструментами для создания облака тэгов.

Скачать можно с моего сайта (34Kb). Просто распакуйте архив в папку проекта и добавьте это приложение в INSTALLED_APPS.


#settings.py
...
INSTALLED_APPS = (
    ...
    'myproject.tagging',
)


Очень просто добавить тэги к любой модели вашего проекта. Для этого нужно импортировать из django-tagging поле TagField


#models.py
...
from tagging.fields import TagField

...

class Item(models.Model):
    ...
    tags = TagField()
    ...


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


#index.html

...

{% tag_cloud_for_model social.Item as item_tags %}

{% for tag in item_tags %}
    <a href="" class="tag" style="font-size:1{{tag.font_size}}pt">
        {{tag}}
    </a>
{% endfor %}

...


Это пример вывода на страницу всех тэгов объекта:


#item.html

...

{% tags_for_object recipe as tag_list %}
{% for tag in tag_list %}
    <a class="tag" href="">
        {{tag}}
    </a>
{% endfor %}

...

суббота, 1 марта 2008 г.

Django tagging для Django 0.96

"django-tagging - Джанго приложение, позволяющее добавлять к объектам любой модели тэги и делающее процесс работы с тэгами проще".
http://code.google.com/p/django-tagging/

На странице скачивания в можно скачать самую новую на текущий момент версию - django-tagging 0.2.1

Для меня проблемма в том, что эта версия не работает с Django 0.96 который установлен на хостинге.

Путем несложных умозаключений пришёл к выводу, что старую версию на сервере никто не удалял. Для того что-бы в списке показались все файлы, выбрал опцию поиска "All downloads". Предположение оказалось верным - вот она, django-tagging 0.1.
Прекрасно заработала в моём проекте. Из минусов версии 0.1 хочу отметить отсутствие облака тэгов.

p.s.: Скорее всего прийдеться таки похачить django-tagging 0.2.1 на предмет совместимости с Django 0.96. Очень уж нужно облако тэгов. О результатах обещаю сообщить :)

пятница, 29 февраля 2008 г.

Windows Vista не определяет флешку

Это широкораспостраненая проблемма в Windows Vista. После вставки флешки в USB порт, Vista долго ищет драйвера и никогда их не находит.

Решение:
Вытащить флешку, удалить из директории \windows\inf\ файлы:
DRVINDEX.DAT
INFPUB.DAT
INFSTOR.DAT
INFSTRNG.DAT
INFCACHE.*
SETUPAPI.*

Вставить флешку. Если автоматически драйвера не установятся - из диспетчера устройств установить драйвер вручную с опцией автоматического поиска (для поиска указать директорию windows\system32). Флешка должна успешно установиться.

Решение подсказал IgorZaz.

среда, 27 февраля 2008 г.

Связка GMail + Django

Про Google Mail не слышал только ленивый. ИМХО, это самая прогрессивная веб-почта. Как адепту Django мне очень приятно думать, что любимый фреймворк тоже самый прогрессивный :)

Но речь не о том, кто круче. Речь о замечательной библиотеке libGmail для Python. Используя эту библиотеку очень просто получать и отправлять письма с GMail.
Например, следующий код отправляет уведомление о необходимости активации аккаунта новому пользователю сервиса:

import libgmail
...

to_email = request.user.email
activation_link = http://dontbeevil.com/activate/%s/ % request.COOKIES["sessionid"]
ga = libgmail.GmailAccount(dontbeevil@gmail.com, "ourpassword")
ga.login()
subject = "Администрация сервиса"
msg = "Дорогой пользователь! Для активации аккаунта воспользуйтесь этой ссылкой: %s" % activation_link
gmsg = libgmail.GmailComposedMessage(to_email, subject, msg)
ga.sendMessage(gmsg)
...


Еще с помощью libGMail можно использовать свой аккаунт GMail как POP или SMTP сервер.
Библиотека распостраняеться по лицензии GPL 2.0.

вторник, 26 февраля 2008 г.

5 инструментов без которых я не могу работать продуктивно

Подключаюсь к флешмобу разработчиков, который затеял TermiT.
Вот моё ТОП 5 инструментов:

1. Firefox + Firebug.

2. Eclipse.

3. Total Commander.

4. Рюкзак с ноутбуком.

5. Интернет, куда уж без коллективного разума.

Передаю эстафету tapo4ku, andrewscater, i-love-python, glader.

Список полезных ресурсов по Django

Сегодня дошли руки оформить список ссылок ресурсов по фреймворку Django. В процессе составления использована информация с форума Python.com.ua

понедельник, 25 февраля 2008 г.

Сервис автозаполнения форм

Вчера, по ссылке из Хабрахабр я зашёл в интернет-магазин купить диск с подшивкой журнала "Наука и Жизнь" за 1990-2005 гг. И снова прошёл унизительную процедуру допроса в виде заполнения здоровенной формы оформления заказа: ФИО, е-мейл, телефон, адрес - одно и тоже. Каждый раз. Это стандартная процедура во всех интернет-магазинах. Это процедура, в которой программы каждый раз показывают свою тупость.

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

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

Почему программе интернет-магазина не спросить меня "визитку"?

суббота, 23 февраля 2008 г.

Python 2.5.2

Доступна новая версия Питона.

Python 2.5.2 являеться вторым багфикс-релизом Python 2.5. По сравнении с версией Python 2.5.1 исправлено более 100 ошибок. Версия 2.5.2 полностью совместима с 2.5.1 и 2.5. По словам разработчиков они работают только над вылавливанием багов и повышением производительности интерпретатора. Оригинал на английском.

Книга «Не мешайте мне работать!»

Вчера скачал книгу Стаса Давыдова «Не мешайте мне работать!».

Жесть! Вспомнил своё устройство на работу и сам рабочий процесс в "Волынской Софтовой Компании". Солидная фирма, крутые перспективы каръерного роста, "круче нас только яйца и горы" и т.д.

Демотивация - она кругом. Только и разговоров - "ты должен", "сделаешь это и будешь на хорошем счету" и т.д. Разве так сложно предложить за дополнительную работу немного денег? Я ведь кот. И хожу на работу исключительно ради денег. Хочешь преданности корпоративным идеалам - заведи собаку!



Рекомендую к прочтению всем утомленным работникам и работницам.
http://motivateme.ru/book/

среда, 20 февраля 2008 г.

Персональные социальные сети

Ехал домой и вспомнил жаркий разговор недельной давности. Тогда, в Карпатах, я с группой стартаперов из GWT Community обсуждал пути развития Веба. Социальные сети сделали нас более дружественными и открытыми. Инициатива "OpenSocial" от Google сделает в недалёком будущем пользователей более свободными от владельцев социальных сетей.

Мы будем подобны кочевникам, перемещаясь из одного сервиса в другой. Ничего не теряя, только расширяя свой "социальный граф". Для определения этого состояния отлично подходит поговорка "Всё своё ношу с собой".

В OpenSocial "Сервер опционален", "...при желании приложение можно разместить на собственных серверах...", новые корневые доменные имена. Прочувствуйте ЭТО.

В начале были персональные авторские сайты. Контент создавался владельцем-автором. Веб 1.0. Следующее поколение ударилось в другую крайность - право на создание контента отдали народу [ссылка для любопытных]. Важной составляющей контента стали разнообразные связи между информацией, в том числе - связи социальные.

Но пользователь всё еще зависим от произвола владельцев сервиса. Не так давно я наткнулся на описание сервиса управления задачами http://8apps.com/. Мне он понравился и каково же было моё разочарование, когда в окне появился текст "8apps is now closed" ("сервис 8 приложений закрыт"). А как быть пользователям, создавшим в этом сервисе свой контент? Ты потратил время, изучил еще одни правила работы с человеко-машинной системой, создал и упорядочил свои задачи и контакты, организовал работу... и - Бамс!!! Создатель стартапа наигрался и всё - приехали!

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

Как вариант развития Веба мне нравиться идея Персональных социальных сетей. Это миллиарды индивидуальных доменов с установленными персональными социальными CMS. Весь контент находиться в ведении автора контента.

Представьте, что вы купили хостинг и зарегистрировали свой домен - например, http://petr.grushevinchuk (.grushevinchuk - это корневой (!) домен). Как мы сейчас устанавливаем WordPress для создания блога, так и для создания персональной социальной сети будет достаточно установить что-то вроде SocialPress. И всё!

Ваша личная социальная сеть готова. Забираете свой "соц. багаж" с FaceBook (или Orkut, кому как больше нравиться) и продолжаете развивать свою социальную жизнь - френдите, комментируете, делитесь фотками и событиями и т.д. Но вся эта информация храниться на вашем личном социальном сервисе. Можно создавать записи только "для друзей" или полностью "личные" и быть уверенными, что после покупки сервиса ЧЧ ваш аккаунт не попадет в руки очень_интересующихся.

Можно вообще обойтись без централизованного сервера и распылять контент по Сети. Подтверждение авторства может осуществляться через контроль ДНК с мобильного терминала. Но это уже другая история...

вторник, 19 февраля 2008 г.

В продолжение темы автономных Джанго-приложений

Продолжение поста 1 минута для старта

Моё маленькое приложение на базе Instant Django работало прекрастно, пока им пользовался один человек. Потом "програмка" понравилась всем сотрудникам отдела и они дружно начали юзать её по сети. И програмка начала дружно виснуть :)

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

То-есть запустив manage.py runserver только один пользователь сможет комфортно работать с приложением. Для работы нескольких пользователей нужно использовать другой веб-сервер. Например - Апач.

Меня не устраивала перспектива топать к друзьям в офис и обьяснять их руководству, зачем им нужен Апач. Тем более что бос был не в курсе, что его подопечные юзают "левое" приложение.

Решением стало использование веб-сервера CherryPy из фреймворка TurboGears. Как использовать CherryPy с Django подробно описано у Гордона Тиллмана.

Вкратце:
1. скачать пакет с CherryPy и поместить его в папку ../Python/lib/site-packages/
2. в папке нашего Джанго-приложения создать 2 файла конфигурации: pieserver.conf и pieserver.py

pieserver.conf

[global]
server.socket_host = "127.0.0.1" #IP вашей машины
server.socket_port = 8080
server.thread_pool = 10
log.screen=True
environment = 'production'


pieserver.py

import sys
import os
import cherrypy

from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler

os.environ["DJANGO_SETTINGS_MODULE"] = "YOURSITE.settings"

class DjangoApp(object):
django_conf = {
'/YOURAPP/media' : {
'tools.staticdir.on' : True,
'tools.staticdir.root' : os.path.abspath(os.path.join(os.path.dirname(__file__),'YOURPROJECT','YOURAPP')),
'tools.staticdir.dir' : 'media',
}
}

if __name__ == '__main__':
sys.path.insert(0,"..")
conf = os.path.join(os.path.dirname(__file__), 'pieserver.conf')
cherrypy.config.update(conf)
cherrypy.tree.graft(AdminMediaHandler(WSGIHandler()), '/')
cherrypy.server.quickstart()
cherrypy.engine.start()


Подкоректируйте параметры staticdir по своему вкусу.

Настройка закончена. Осталось запустить pieserver.py

воскресенье, 17 февраля 2008 г.

Переводы статей Пола Грэма (Paul Graham)

По адресу http://tony.stereoclick.com/ силами Антона Рубана была собрана лучшая по-моему мнению подборка ссылок на переводы статей Пола Грема.
Теперь эта страница больше не существует. Увы.

Вот её копия из кеша WayBackMachine:

суббота, 2 февраля 2008 г.

1 минута для старта

Пишу автономное приложение на Python+Django. Нужно, что бы оно работало без установки и настройки на других компьютерах. Погуглив, нашел - Instant Django, http://www.instantdjango.com.

В комплекте: Python 2.5, Django trunk, PIL, SVN, Sqlite3. Всё распаковывается в одну папку и запускаеться файлом start.bat. Платформа готова для поддержки жизнеобеспечения нашего приложения :)

среда, 23 января 2008 г.

Потоковое видео - это можно!

Дать пользователям возможность показать себя в конкурсе с помощью видеоролика - 
это будет круто, подумал я. Осталось добавить поддержку потокового видео в сервис.
Это оказалось совсем несложно, все элементарно:
 - Адрес видеоролика YouTube выглядит примерно так: http://www.youtube.com/watch?v=CtQjOkL6YlM (или http://ru.youtube.com/watch?v=CtQjOkL6YlM если это RuTube)
 - Идентификатор видеофайла здесь находится как значение параметра - CtQjOkL6YlM
 - Адрес к превью - http://img.youtube.com/vi/CtQjOkL6YlM/default.jpg
Что-бы поместить плеер в страницу нужно заюзать следующую конструкцию:

<object width='425' height='355'>
<param name='movie' value='http://www.youtube.com/v/CtQjOkL6YlM&rel=1'>
</param>
<param name='wmode' value='transparent'>
</param>
<embed src='http://www.youtube.com/v/CtQjOkL6YlM&rel=1' type='application/x-shockwave-flash' wmode='transparent' width='425' height='355'>
</embed>
</object>
Значения параметров width и height можно свободно варьировать.

Вот собственно и все дела с потоковым видео :)

Центровка в DIV по вертикали - хак для IE

Написав в CSS "vertical-align: middle;" можно получить вертикальное выравнивание контента внутри DIV в Firefox, Opera, Safari. Но не в Internet Explorer.

<div class="contest_logo">
<img src="http://www.blogger.com/{{%20featured_contest.contest.get_logo%20}}" />
</div>

Высота DIVа класса "contest_logo" фиксированная. Это рамка логотип конкурса. Конкурсы выводяться списком. Вот здесь.
Но вот картинки-логотипы имеют разную высоту. И их нужно выровнять внутри рамки по вертикали.

Решение для "нормальных" броузеров:
.contest_logo {
width: 252px;
height: 213px;
padding: 4px;
border:1px solid #9dbaec;
text-align: center;
display: table-cell;
vertical-align: middle;

}

Но в IE это не работает. Погуглив немного, нашел элегантное решение:
.contest_logo img {
vertical-align: middle;
margin-top: expression((213-height)/2 + "px");
}

IE поддерживает использование в CSS оператора expression(), внутри которого
можно поместить код на JavaScript.

вторник, 22 января 2008 г.

Документация по Django в одном файле

Один хороший человек взял и скомпилировл всю документацию из
http://www.djangoproject.com/documentation/
в виде CHM-файла. Честь ему и слава!

Скачать можно отсюда:
http://charupload.wordpress.com/2007/12/02/django-documentation-chm/
(1,3Мб)

з.ы.: только что скачал. Файл регулярно обновляеться ;)

вторник, 15 января 2008 г.

Всему своё время

Есть время собирать камни, и есть время выносить мусор. Или как-то так. 

Когда же оно наступает, это "правильное время" что-то делать? ИМХО, тут нужно положиться на чутье, сигналы от подсознания. Когда подсознание тихо шепчет - "давай, действуй", - вот тогда и наступило время Икс.

У нас в сервисе не было предусмотрено места для рекламы. С другой стороны, мысли размещать контекстную рекламу на страницах были. Вчера послеобеда (угу, кто же на голодный желудок работает) решил добавить на главной странице панель для 10ти свежих комментариев. Симпатично получилось. И динамично, что тоже плюс для ботов поисковых систем. Можете посмотреть.

И вот тут до меня дошло! На остальных страницах ведь тоже появилась эта панель. И если на главной странице её назначение - выводить комментарии, - то на остальных страницах она пустует. Немного поправив CSS я сделал е пригодной для размещения стандартных баннеров 150х200. До трех штук на странице. Уже сейчас количество страниц превышает 200 (страницы конкурсов, участников конкурсов, списков участников и т.д.).

Вечером того же дня для пустующих рекламных площадок нашелся рекламодатель. Вот так - всему своё время.

понедельник, 14 января 2008 г.

Что же тебе нужно?

Сегодня пытался выбить из потенциального заказчика признание, что же ему нужно на_самом_деле? Победа над конкурентами, успех! Да? А мне почему-то показалось - больше функций, картинок, текста. Чем сложнее представление о проекте с самого начала, тем больше вероятность затягивания.

Мы поставили в проекте "Конкурсоф.Нет" в приоритете не функциональность. Приоритет - запуск в продакшн. Да, вы наверное подумаете, что это глупо - предоставлять пользователям не рабочую версию программы. И разумеется будете правы.

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

Когда мне нужно написать пару строк текста, я напишу его и в обычном текст-боксе. Однако, большинство разработчиков сервисов почему-то считают, что без WYSIWYG редактора ну просто не обойтись. Плюс еще пару-тройку таких "жизненно важных" функций, и запуск сервиса откладываеться на месяц, два и т.д.

Простите, но к этому времени мы уже получим долю рынка!

Почитайте Getting Real на ночь. Очень протрезвляет.
  • Меньше возможностей
  • Меньше опций и настроек
  • Меньше структура компании
  • Меньше встреч и абстракций
  • Меньше обещаний
Да, вот так это работает.

воскресенье, 13 января 2008 г.

Дисклаймер

Мой друг (а теперь и партнер по стартапу) давно мечтал проводить конкурсы. Сколько я его помню, он носился с этой идеей. Еще у него была одна болезнь, к которой судя по моим личным наблюдениям, склонны начинающие веб-программисты. "Нужно написать свой движек! Движек - это ключ" и т.д.

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

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

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

Вот и весь дисклаймер :)

Со Старым Новым Годом, друзья!

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