Захотелось/потребовалось дублировать информацию с сайта под друпалом в LiveJournal.
Нашел модуль LiveJournal CrossPoster (он же ljxp), который умеет кроспостить материал создаваемый на сайте сразу в жж. Установил, настроил - все заработало. Но у него было два не очень удобных, для меня, момента:
Т.к. с PHP дружу не очень, а на нем написаны этот модуль и сам друпал, и еще хуже представляю как пишутся модули под друпал, пришлось все делать с помощью жесткого лома (на сколько я понял, в сообществе друпалистов, называется это хаком).
Дальше опищу как что делал, в конце прикреплю поправленный мною файл ljxp.module модуля.
Тут возникло два момента:
Привожу patch файла ljxp.module этого модуля для этого решения:
43,44c43
< !user_access('can crosspost to livejournal') ||
< $user->uid != $form['uid']['#value']) {
---
> !user_access('can crosspost to livejournal') ) {
93c92
< if (!user_access('can crosspost to livejournal') || $GLOBALS['user']->uid != $node->uid) {
---
> if (!user_access('can crosspost to livejournal') ) {
239c238
< if (user_access('can crosspost to livejournal', $account) && ($user->uid == $account->uid || user_access('administer site configuration'))) {
---
> if (user_access('can crosspost to livejournal', $account) && (user_access('administer site configuration'))) {
298a298
> $uid=1;
315a316
> $uid=1;
Соответственно, в данном случае у нас все настройки берутся от пользователя с UID равным 1. С точки зрения безопасности не очень красиво, т.к. любой пользователь, которому разрешено пользоваться этим модулем может изменить настройки публикации. При желании, можно после настройки вырезать лишние части из функции ljxp_user. Не очень красиво, но очень надежно.
Изначально, хотел сделать красиво, т.е. чтобы статья сначала публиковалась в ЖуЖу с текущим временем и сразу же автоматом изменяла на время публикации, но терпения и мозгов не хватило и сделал публикацию всех статей с текущим временем.
P.S. Несколько поменялась стратегия. Первый раз все публикуется с текущим временем + несколько лет вперед. При обновлении поста, дата публикации меняется на правильную. Уже немного удобнее, но так и не получилось сделать , чтобы не требовалось два раза ручками публиковать. :-(
Для этого, в том же файле ljxp.module изменил строки:
$message['year'] = format_date($node->created, 'custom', 'Y');
$message['mon'] = format_date($node->created, 'custom', 'n');
$message['day'] = format_date($node->created, 'custom', 'j');
$message['hour'] = format_date($node->created, 'custom', 'G');
$message['min'] = format_date($node->created, 'custom', 'i');
На:
$publish_time=$node->created;
// Если статья публикуется первый раз, то дату публикации в LJ увеличиваем на несколько лет.
if (!$node->ljid) $publish_time=time()+100000000;$message['year'] = format_date($publish_time, 'custom', 'Y');
$message['mon'] = format_date($publish_time, 'custom', 'n');
$message['day'] = format_date($publish_time, 'custom', 'j');
$message['hour'] = format_date($publish_time, 'custom', 'G');
$message['min'] = format_date($publish_time, 'custom', 'i');
Соответственно, для того чтобы все снова публиковалось с правильным временем или все возвращаем обратно или комментируем строку "if (!$node->ljid) $publish_time=time()+100000000;".
Т.к. одной большой кнопки "сделать все зашибись" не нашлось, а руками протыкивать по два раза по всем материалам было тоскливо и при этом расковыривать друпал дальше было лень, начал вспоминать, как можно автоматизировать работу в браузере.
У фаерфокса есть дополнение iMacros, с помощью его и sh данный процес и автоматизировал.
На баше нарисовал скриптик, который формировал сценарий действий для iMacros следующего содержания:
#!/bin/sh
site=$1
cur_post=$2
LIMIT=$3
echo "VERSION BUILD=7401110 RECORDER=FX"
while [ $cur_post -le "$LIMIT" ]
do
echo "URL GOTO=${site}/node/${cur_post}/edit
TAG POS=1 TYPE=LABEL ATTR=TXT:Crosspost<SP>to<SP>LiveJournal
TAG POS=1 TYPE=INPUT:CHECKBOX FORM=ACTION:/node/${cur_post}/edit ATTR=ID:edit-ljxp-crosspost CONTENT=YES
TAG POS=1 TYPE=LABEL ATTR=TXT:Создать<SP>новую<SP>редакцию
TAG POS=1 TYPE=INPUT:CHECKBOX FORM=ACTION:/node/${cur_post}/edit ATTR=ID:edit-revision CONTENT=NO
TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:node-form ATTR=ID:edit-submit
"
cur_post=$(($cur_post+1))
done
Запускаем его соответственно со следующими параметрами site start_post end_post, где:
Полученный сценарий скармливаем уже iMacros'у. В итоге фаерфокс пробегает по всем нодам, выставляет у них галочку "публиковать в живом журнале", снимает галочку "Создать новую редакцию" и сохраняет их.
Т.к. на сайте, с которым я все это делал, было порядка 100 нод, оно вполне нормально отработало. К сожалению, в случае удаленных публикаций скрипт переставал работать и вставал. Найти галочку "продолжать работу в случае ошибок" у меня на вскидку не получилось, по этому пришлось делать кусками.
Более правильный подход - анализировать sitemap. Скрипт который наваял под это дело:
#!/bin/sh
site=$1
sitemap=$2
if [ $# -lt 3 ]; then
type_content="node"
else
type_content=$3
fi
echo "VERSION BUILD=7401110 RECORDER=FX"
for cur_post in ` wget -q -O - $2 | grep $type_content | grep -v "#comments" | sed "s/^.*\/${type_content}/${type_content}/" | sed 's/<.*$//'`
do
echo "URL GOTO=${site}/${cur_post}/edit
TAG POS=1 TYPE=LABEL ATTR=TXT:Crosspost<SP>to<SP>LiveJournal
TAG POS=1 TYPE=INPUT:CHECKBOX FORM=ACTION:/${cur_post}/edit ATTR=ID:edit-ljxp-crosspost CONTENT=YES
TAG POS=1 TYPE=LABEL ATTR=TXT:Создать<SP>новую<SP>редакцию
TAG POS=1 TYPE=INPUT:CHECKBOX FORM=ACTION:/${cur_post}/edit ATTR=ID:edit-revision CONTENT=NO
TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:node-form ATTR=ID:edit-submit
"
done
Принимает следующие параметры site sitemap node_type, где:
Была мысля сделать чтобы разбирало RSS и тому подобное, но пока сломался.