Наверное уже можно :)
http://demalexx.org
18 декабря 2009 г.
21 ноября 2009 г.
Сервисы Google и Python
Наткнулся в журнале Хакер на статью про использование сервисов Гугла в Питоне. Мощная штука! :) Можно работать, например, с блоггером, почтой, таблицами, документами и т.д.
Начать нужно с Google Data Protocol - страницы протокола, который используется для работы с API гугловых сервисов. Там есть библиотечки для разных языков.
Хотя, это API какое-то странное и не очевидное... Вот простой пример, который печатает в консоль все посты дефолтного блога пользователя demalexx@gmail.com.
Начать нужно с Google Data Protocol - страницы протокола, который используется для работы с API гугловых сервисов. Там есть библиотечки для разных языков.
Хотя, это API какое-то странное и не очевидное... Вот простой пример, который печатает в консоль все посты дефолтного блога пользователя demalexx@gmail.com.
# -*- coding:utf-8 -*-
'''This script prints all blog posts from blogger.com'''
from gdata import service
import gdata
import atom
blogger_service = service.GDataService('demalexx@gmail.com', 'password')
blogger_service.source = ''
blogger_service.service = 'blogger'
blogger_service.account_type = 'GOOGLE'
blogger_service.server = 'www.blogger.com'
blogger_service.ProgrammaticLogin()
query = service.Query()
query.feed = '/feeds/default/blogs'
feed = blogger_service.Get(query.ToUri())
blog_id = feed.entry[0].GetSelfLink().href.split("/")[-1]
feed = blogger_service.GetFeed('/feeds/' + blog_id + '/posts/default')
print feed.title.text
for entry in feed.entry:
print "\t" + entry.title.text.decode('utf-8')Вывод:D:\Projects\python\google>get_blogger_posts.py
race1
Сервисы Google и Python
PAP Affiliate и eAccelerator
SSH - аутентификация ключом
...
20 ноября 2009 г.
PAP Affiliate и eAccelerator
На сайте стоит eAccelerator и потом я поставил PAP Affiliate. С самого начала этот пап работал очень медленно. Настолько медленно, что оставлял после себя процессы httpd, работающие по несколько часов и потребляющие все ресурсы процессора. Единственный выход был в перезагрузке Апача, но это спасало не надолго.
Интересна реакция саппорта. Они просили проверить настройки электропочты. Типа проблема в этом. Хотя письма как раз отправлялись. Попробовал я поменять эти настройки - в настроках PAP сделал отправку писем не функцией mail(), а используя SMTP сервер - ничего лучше не стало, конечно.
Как временная мера - установил лимит на выполнение скриптов из папки PAP в 30 секунд :)
В общем в итоге всё оказалось просто. PAP не работает с eAccelerator. Вот страница у них на сайте, где говорится что они знакомы с проблемой, и ничего не собираются с ней делать: http://support.qualityunit.com/knowledgebase/post-affiliate-pro/troubleshooting/eaccelerator-module-installed-at-server.html.
Что бы решить проблему нужно выключить eAccelerator для скриптов из папки PAP. Для этого я создал файл
Теперь PAP просто летает, а eAccelerator работает для всего остального сайта.
PS. Удалил eAccelerator, заменил его APC. Он, говорят лучше, плюс от создателей PHP. И PAP с ним работает.
Интересна реакция саппорта. Они просили проверить настройки электропочты. Типа проблема в этом. Хотя письма как раз отправлялись. Попробовал я поменять эти настройки - в настроках PAP сделал отправку писем не функцией mail(), а используя SMTP сервер - ничего лучше не стало, конечно.
Как временная мера - установил лимит на выполнение скриптов из папки PAP в 30 секунд :)
В общем в итоге всё оказалось просто. PAP не работает с eAccelerator. Вот страница у них на сайте, где говорится что они знакомы с проблемой, и ничего не собираются с ней делать: http://support.qualityunit.com/knowledgebase/post-affiliate-pro/troubleshooting/eaccelerator-module-installed-at-server.html.
Что бы решить проблему нужно выключить eAccelerator для скриптов из папки PAP. Для этого я создал файл
/var/www/vhosts/centurysupplements.com/conf/vhost.conf (конфиг Апача для виртуального хоста), и написал туда такой текст:<Directory /var/www/vhosts/centurysupplements.com/httpdocs/affiliate>
php_admin_value eaccelerator.enable 0
</Directory>Т.е. выключить eAccelerator для папки /var/www/vhosts/centurysupplements.com/httpdocs/affiliate (там установлен PAP).Теперь PAP просто летает, а eAccelerator работает для всего остального сайта.
PS. Удалил eAccelerator, заменил его APC. Он, говорят лучше, плюс от создателей PHP. И PAP с ним работает.
15 ноября 2009 г.
SSH - аутентификация ключом
Вот здесь хорошая документация, первоисточник - http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter8.html.
В SSH можно авторизоваться либо паролем, либо ключом. Авторизация ключом более секурная, но настраивается на 5 минут дольше авторизации паролем (которая просто уже есть) :) А ещё, используя авторизацию ключом, можно избавиться от ввода пароля, правда это будет уже не так секурно.
Суть в том, что генерируется пара ключей - приватный и публичный. Приватный ключ находится только у пользователя, и используется для шифрования сигнатуры (кража приватного ключа означает то же самое, что кража пароля). Расшифровать сигнатуру можно публичным ключом, который нужно поместить на сервер. При аутентицикации Putty генерирует сигнатуру, которая шифруется приватным ключом, и отправляет её серверу. Сервер, используя публичный ключ, расшифровывает сигнатуру и проверяет её. Т.е. авторизация пройдёт только в том случае, если сигнатура зашифрована приватным ключом пользователя. Это более секурно, потому что даже получив доступ к серверу, злоумышленник не узнает приватного ключа (который хранится у пользователя), в отличие от пароля (который хранится на сервере). Правда для этого очевидно нужно отключить авторизацию по паролю на сервере...
По-хорошему приватный ключ тоже следует зашифровать. Но тогда при каждм соединении по SSH нужно будет вводить пароль для рассшифровки приватного ключа. Если же приватный ключ не шифровать, и указать в Putty имя пользователя для входа - вводить пароли не нужно будет вообще. А только следить что бы приватный ключ никто не стырил :)
Для генерирования ключей нужно взять программку PuttyGen. С её помощью сгенерировать пару ключей. Публичный ключ нужно поместить в файл
В Putty во вкладке
Готово. Теперь при соединении аутенификация будет происходить по ключу, не нужно вводить ни логин, ни пароль. Удобно :)
В SSH можно авторизоваться либо паролем, либо ключом. Авторизация ключом более секурная, но настраивается на 5 минут дольше авторизации паролем (которая просто уже есть) :) А ещё, используя авторизацию ключом, можно избавиться от ввода пароля, правда это будет уже не так секурно.
Суть в том, что генерируется пара ключей - приватный и публичный. Приватный ключ находится только у пользователя, и используется для шифрования сигнатуры (кража приватного ключа означает то же самое, что кража пароля). Расшифровать сигнатуру можно публичным ключом, который нужно поместить на сервер. При аутентицикации Putty генерирует сигнатуру, которая шифруется приватным ключом, и отправляет её серверу. Сервер, используя публичный ключ, расшифровывает сигнатуру и проверяет её. Т.е. авторизация пройдёт только в том случае, если сигнатура зашифрована приватным ключом пользователя. Это более секурно, потому что даже получив доступ к серверу, злоумышленник не узнает приватного ключа (который хранится у пользователя), в отличие от пароля (который хранится на сервере). Правда для этого очевидно нужно отключить авторизацию по паролю на сервере...
По-хорошему приватный ключ тоже следует зашифровать. Но тогда при каждм соединении по SSH нужно будет вводить пароль для рассшифровки приватного ключа. Если же приватный ключ не шифровать, и указать в Putty имя пользователя для входа - вводить пароли не нужно будет вообще. А только следить что бы приватный ключ никто не стырил :)
Для генерирования ключей нужно взять программку PuttyGen. С её помощью сгенерировать пару ключей. Публичный ключ нужно поместить в файл
.ssh/authorized_keys2 в домашней папке на сервере. Каждая строка файла - отдельный публичный ключ. Приватный ключ нужно сохранить куда-то на компьютере.В Putty во вкладке
SSH->Auth нужно указать приватный ключ в поле Private key file for authentication. Что бы Putty автоматически использовала имя пользователя для входа, его нужно прописать в поле Auto-login username, во вкладке Connection->Data.Готово. Теперь при соединении аутенификация будет происходить по ключу, не нужно вводить ни логин, ни пароль. Удобно :)
HeidiSQL через SSH
Оказывается, настроить HeidiSQL (фронтэнд к MySql) для работы с удалённой базой через SSH оказалось не просто, а очень просто :) На удивление такой вариант работает гораздо быстрее чем phpMyAdmin, и потребляет совсем немного трафика. А ещё это более производительный вариант - серверу не нужно обрабатывать множество http запросов от phpMyAdmin. В общем, теперь можно забыть phpMyAdmin как страшный сон, и очень удобно работать с локальными полноценными приложениями типа HeidiSQL и другими.
Итак, что бы это заработало, нужно настроить туннелирование в Putty и настроить соединение в HeidiSQL.
Итак, что бы это заработало, нужно настроить туннелирование в Putty и настроить соединение в HeidiSQL.
Настройка Putty
Во вкладке SSH->Tunnels нужно добавить новый туннель, гдеSource это локальный порт, который будет связан с портом на сервере (который слушает MySQL). Порт 3306 занят локальным MySQL, поэтому укажем порт 3307. Destination это имя хоста и порт MySQL на сервере (по-умолчанию 3306), указываем localhost:3306. Всё, теперь все запросы на локальный порт 3307 будут перенаправлены на порт 3306 на сервере.Настройка HeidiSQL
Создаём новое соединение, указываем хостlocalhost, и порт 3307. Ещё нужно указать логин/пароль для доступа к базам. Готово.
22 октября 2009 г.
Magento, products sitemap
На сайте есть обычные продукты, которые можно продавать, и есть специальная категория Glossary, в которой находятся определения - такие продукты нельзя купить :) Т.е. список определений сделан через категорию, это оказалось достаточно удобно.
Проблема в том, что автогенерируемая страница с картой сайта показывает все активные продукты, в том числе и из категории Glossary. Вот этого и надо избежать. Да, и ещё нужно отсортировать продукты по алфавиту.
Сначала я попробовал сделать категорию Glossary неактивной. Ничего не вышло, Sitemap по-прежнему отображал все продукты. Вариант "выключить" все продукты категории Glossary - вообще не вариант :) Т.е. нигде в настройках в админике, и в xml, нельзя задать ни список категорий для исключения, ни порядка сортировки (может я плохо искал?).
Значит надо делать это вручную. Можно либо поменять ядрёные файлы (оставив нетронутыми шаблонные файлы) - блок
Шаблон странички Sitemap находится в файле
Мы добавим новый массив, который будет содержать продукты, теже объекты, что и коллекция. Но этот массив не будет содержать "продуктов" категории Glossary. После формирования массива вызовем функцию usort и отсортируем массив по названиям продуктов.
Что бы узнать, в каких группах находится текущий продукт, нужно вызвать метод getCategoryIds - он вернёт массив id категорий. Только нужно не забывать, что один и тот же шаблон
Итак, вот код, формирующий новый массив без "продуктов" категории Glossary, и упорядоченный по именам объектов:
Остальной код, по выводу продуктов, остаётся нетронутым, кроме перебора не коллекции
Сразу же после просмотра результата стал заметен баг - хотя продукты из категории Glossary теперь не отображаются, кол-во продуктов выводимое сразу перед списком продуктов (130 Item(s)) осталось прежним.
Поправить это оказалось чуть посложнее. Код, выводящий эту информацию, - шаблон
Код использует исходную коллекцию, содержащую все продукты, её размер соответственно больше чем нужно. Выход - написать свой шаблон, который подкорректирует кол-во продуктов, выводимое на экран.
Создаим этот шаблон -
Сначала посчитаем продукты, исключая продукты из категории Glossary:
Т.к. Sitemap отображает вообще всё что есть на одной странице (это сделано уже давно), то и весь код пейджера, рисующий номера страниц, не нужен - оставим только тот код, который выводит кол-во элементов на одной странице:
Ещё нужно сказать Magento что мы хотим использовать наш шаблон в файле
Последнее - кол-во продуктов выводится не только вверху, но и внизу. Для коррекции выводимого кол-ва так же просто поменяем шаблон в файле
Вот, готово. Теперь Products Sitemap исключает продукты категории Glossary, и выводит правильное кол-во продуктов. Страница Category Sitemap не падает и выводит все категории :)
Изменённые файлы:
Проблема в том, что автогенерируемая страница с картой сайта показывает все активные продукты, в том числе и из категории Glossary. Вот этого и надо избежать. Да, и ещё нужно отсортировать продукты по алфавиту.
Сначала я попробовал сделать категорию Glossary неактивной. Ничего не вышло, Sitemap по-прежнему отображал все продукты. Вариант "выключить" все продукты категории Glossary - вообще не вариант :) Т.е. нигде в настройках в админике, и в xml, нельзя задать ни список категорий для исключения, ни порядка сортировки (может я плохо искал?).
Значит надо делать это вручную. Можно либо поменять ядрёные файлы (оставив нетронутыми шаблонные файлы) - блок
catalog/seo_sitemap_product, изменить его так, что бы он исключал категорию Glossary и сортировал продукты. Понятно, почему это плохой вариант, и мы так делать не будем :) Вместо этого мы будем менять только шаблонные файлы. Вообще решение этой проблемы добавит немало безнес-логики в шаблоны. Не очень хорошо, но с этим можно жить :) Зато без переделки ядрёных файлов. Шаблон странички Sitemap находится в файле
template/catalog/seo/sitemap.phtml. Существующий код берёт коллекцию всех продуктов (полученную в соответствующем блоке) и выводит все её элементы.Мы добавим новый массив, который будет содержать продукты, теже объекты, что и коллекция. Но этот массив не будет содержать "продуктов" категории Glossary. После формирования массива вызовем функцию usort и отсортируем массив по названиям продуктов.
Что бы узнать, в каких группах находится текущий продукт, нужно вызвать метод getCategoryIds - он вернёт массив id категорий. Только нужно не забывать, что один и тот же шаблон
template/catalog/seo/sitemap.phtml используется для вывода как продуктов, так и категорий. Если вызвать getCategoryIds у объекта-категории, он вернёт null. Нужно специально обработать этот случай.Итак, вот код, формирующий новый массив без "продуктов" категории Glossary, и упорядоченный по именам объектов:
<?php $_items = $this->getCollection(); ?>
<?php
// Original collection is not ordered. To sort items by name
// we'll use array, then we'll sort it by name. Array will
// contain the same objects as original collection
$items = array();
// Create our array, excluding Glossary category (id == 63)
foreach ($_items as $_item) {
if (is_array($_item->getCategoryIds()) && in_array(63, $_item->getCategoryIds()))
continue;
$items[] = $_item;
}
function cmp($a, $b) {
return strcmp($a->getName(), $b->getName());
}
usort($items, cmp);
?>Остальной код, по выводу продуктов, остаётся нетронутым, кроме перебора не коллекции
$_items, а нового массива $items.Сразу же после просмотра результата стал заметен баг - хотя продукты из категории Glossary теперь не отображаются, кол-во продуктов выводимое сразу перед списком продуктов (130 Item(s)) осталось прежним.
Поправить это оказалось чуть посложнее. Код, выводящий эту информацию, - шаблон
template/page/html/pager.html. И используется он в catalog.xml вот так:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/template_links" name="seo.sitemap.links" as="links" template="page/template/links.phtml"/>
<!-- Magento adds block with template "page/html/pager.phtml" -->
<block type="page/html_pager" name="seo.sitemap.pager.top" as="pager_top" template="page/html/pager.phtml"/>
...Код использует исходную коллекцию, содержащую все продукты, её размер соответственно больше чем нужно. Выход - написать свой шаблон, который подкорректирует кол-во продуктов, выводимое на экран.
Создаим этот шаблон -
template/catalog/seo/sitemap/mypager.phtml. Сначала посчитаем продукты, исключая продукты из категории Glossary:
<?php // Calc products that don't belong to Glossary category (63) ?>
<?php // We already hide glossary "products" from sitemap page, now we need ?>
<?php // to correct products count ?>
<?php $productsCountWithoutGlossary = 0; ?>
<?php foreach ($this->getCollection() as $_i) { ?>
<?php if (is_array($_i->getCategoryIds()) && in_array(63, $_i->getCategoryIds())) continue; ?>
<?php $productsCountWithoutGlossary++; ?>
<?php } ?>Т.к. Sitemap отображает вообще всё что есть на одной странице (это сделано уже давно), то и весь код пейджера, рисующий номера страниц, не нужен - оставим только тот код, который выводит кол-во элементов на одной странице:
<table class="pager" cellspacing="0">
<tr>
<td>
<strong><?php echo $this->__('%s Item(s)', $productsCountWithoutGlossary) ?></strong>
</td>
</tr>
</table>Ещё нужно сказать Magento что мы хотим использовать наш шаблон в файле
catalog.xml:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/template_links" name="seo.sitemap.links" as="links" template="page/template/links.phtml"/>
<!-- Replace default template with ours "catalog/seo/sitemap/mypager.phtml" -->
<block type="page/html_pager" name="seo.sitemap.pager.top" as="pager_top" template="catalog/seo/sitemap/mypager.phtml"/>
...Последнее - кол-во продуктов выводится не только вверху, но и внизу. Для коррекции выводимого кол-ва так же просто поменяем шаблон в файле
catalog.xml:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/html_pager" name="seo.sitemap.pager.bottom" as="pager_bottom" template="catalog/seo/sitemap/mypager.phtml"/>
...Вот, готово. Теперь Products Sitemap исключает продукты категории Glossary, и выводит правильное кол-во продуктов. Страница Category Sitemap не падает и выводит все категории :)
Изменённые файлы:
- app/design/frontend/default/sunnyD/layout/catalog.xml
- app/design/frontend/default/sunnyD/template/catalog/seo/sitemap.phtml
- app/design/frontend/default/sunnyD/template/catalog/seo/sitemap/mypager.phtml
20 октября 2009 г.
Magento, права
Я уже описывал как делать модули, имеющий интерфейс в админке (и пункт меню там же), но этот модуль никак не работал с разрешениями (permissions). Как оно действует по-умолчанию я не знаю - либо показывает меню всем, либо показывает только администратору.
Сейчас я добавил в
Я так понимаю, что т.к. мой модуль находится внутри пункта меню верхнего уровня Catalog, то нужно добавить его. А называется модуль (или пункт меню?)
Как бы то ни было, теперь право просматривать страницу модуля BlogRewrites можно назначить в Admin - System - Permissions - Roles:

А на будущее надо бы по-лучше поизучать как работают права в Magento.
Сейчас я добавил в
config.xml модуля немного "кода", так, что теперь можно выбрать, может ли пользователь работать с пунктом меню или нет. Как-то так :) Информации по этому очень мало...<?xml version="1.0"?>
<config>
...
<adminhtml>
<menu>
<catalog module="catalog">
<children>
<blogrewrite translate="title" module="blogrewrite">
<title>Blog Rewrite</title>
<action>blogrewrite/adminhtml_blogrewrite</action>
</blogrewrite>
</children>
</catalog>
</menu>
<acl>
<resources>
<admin>
<children>
<catalog>
<children>
<blogrewrite>
<title>Blog Rewrites</title>
</blogrewrite>
</children>
</catalog>
</children>
</admin>
</resources>
</acl>
</adminhtml>
</config>Я так понимаю, что т.к. мой модуль находится внутри пункта меню верхнего уровня Catalog, то нужно добавить его. А называется модуль (или пункт меню?)
blogrewrite.Как бы то ни было, теперь право просматривать страницу модуля BlogRewrites можно назначить в Admin - System - Permissions - Roles:

А на будущее надо бы по-лучше поизучать как работают права в Magento.
Подписаться на:
Сообщения (Atom)