Статьи

Используйте Mule для синхронизации сайтов WordPress


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

  • Получите RSS-канал о новом сообщении в Mule flow
  • Используйте содержимое RSS-канала для публикации в другом экземпляре WordPress с помощью XML-RPC.
  • Запустите его на CloudHub, чтобы мне не пришлось настраивать свой собственный Muleserver

Итак, давайте начнем новый проект CloudHub . Поскольку я большой поклонник Netbeans, я использую подход, основанный на Maven (должен признать, что я пытался использовать MuleStudio для этого, но это не принесло мне повышения производительности, на которое я надеялся).
Я создал проект Mule с:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:http="http://www.mulesoft.org/schema/mule/http"
      xmlns:rss="http://www.mulesoft.org/schema/mule/rss"
      xmlns:spring="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="
        http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.1/mule.xsd
        http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.1/mule-http.xsd
        http://www.mulesoft.org/schema/mule/rss http://www.mulesoft.org/schema/mule/rss/3.1/mule-rss.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <spring:bean name="xmlRpcHelper" class="net.pascalalma.rss.XmlRpcHelper">
        <spring:constructor-arg value="http://www.pragmatic-integrators.com/xmlrpc.php" type="java.lang.String"/>
        <spring:constructor-arg value="UserName" type="java.lang.String"/>
        <spring:constructor-arg value="Password" type="java.lang.String"/>
    </spring:bean>
    <spring:bean name="entryReceiver" class="net.pascalalma.rss.EntryReceiver">
        <spring:constructor-arg ref="xmlRpcHelper"/>
    </spring:bean>
    <flow name="poll-and-post">
        <poll frequency="36000000">
            <http:outbound-endpoint address="http://www.redstream.nl/feed/" />
        </poll>
        <rss:feed-splitter />
        <component>
            <spring-object bean="entryReceiver"/>
        </component>
    </flow>
</mule>

Как видите, я опрашиваю сайт «www.redstream.nl» один раз каждые 10 часов. RSS-канал, который я получаю, разделяется и отправляется в мой пользовательский компонент entryReceiver. Было бы хорошо , чтобы использовать XML-RPC конечной точки здесь , но это не будет создан еще (и на самом деле я не чувствую , как это ни). EntryReceiver выглядит так:

package net.pascalalma.rss;

import org.mule.api.annotations.param.Payload;
import com.sun.syndication.feed.synd.SyndEntry;

public class EntryReceiver {

    XmlRpcHelper xmlRpcHelper = null;

    public EntryReceiver(XmlRpcHelper helper) {
        xmlRpcHelper = helper;
    }
    public void readEntry(@Payload SyndEntry entry) throws Exception {

        // Get the title
        String title = entry.getTitle();

        // Check if title exist in current blogs on the new blogsite
       if (!xmlRpcHelper.titleExists(title)) {
            xmlRpcHelper.post(entry);

        } else {
            // Skip this post
        }
    }
}

Отказ от ответственности: просто хотел посмотреть, работает ли он, я не пытался создать надежное решение, которое должно было бы работать для каждого сайта WordPress, так что вы предупреждены!

И боб, где сделана грязная работа:

package net.pascalalma.rss;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;

public class XmlRpcHelper {

    private String url;
    private String userName;
    private String password;
    XmlRpcClient client = new XmlRpcClient();

    public XmlRpcHelper(String url, String u, String p) {
        this.url = url;
        this.userName = u;
        this.password = p;

        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        try {
            config.setServerURL(new URL(url));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        client.setConfig(config);
    }

    public boolean titleExists(String title) {
        return getRecentTitles().contains(title);
    }

    public void post(SyndEntry entry) {
        StringBuilder content = new StringBuilder("<content><title>").append(entry.getTitle()).append("</title>");
        List<SyndContentImpl> contents = entry.getContents();

        for (SyndContentImpl syndContent : contents) {
            content.append(syndContent.getValue());
        }
        content.append("</content>");
        try {
            client.execute("blogger.newPost", new Object[]{"bla", 1,
                        userName, password, content.toString(), true});
        } catch (XmlRpcException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private List<String> getRecentTitles() {
        List<String> titles = new ArrayList<String>();
        try {
            Object token = client.execute("blogger.getRecentPosts", new Object[]{"bla", 1,
                        userName, password, 10});

            Object[] result = (Object[]) token;
            for (int i = 0; i < result.length; i++) {
                titles.add(getTitle((HashMap<String, Object>) result[i]));
            }
        } catch (XmlRpcException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            // return null;
        }
        return titles;
    }

    private static String getTitle(Map response) {
        String title = null;
        String content = (String) response.get("content");

        if (content != null) {
            title = content.substring(content.indexOf("<title>") + 7,
                    content.indexOf("</title>"));
        }
        return title;
    }
}

Некоторое время я был занят тем, что первая строка в массиве объектов, поставляемая с вызовом XmlRpc, может содержать что угодно, если только она содержит что-то. Пустая строка «» игнорируется в вызове и приведет к неверному сообщению имени пользователя / пароля.

Если все это есть, вы можете собрать проект с помощью: ‘mvn clean install’. Это создаст zip-файл в целевой директории. Этот zip-файл может быть загружен с вашей приборной панели в ваш экземпляр CloudHub и все! Как вы можете видеть, два сайта «www.redstream.nl» и «www.pragmatic-integrators.com» синхронизированы (с максимальным разрывом в 10 часов). Конечно, скопированный пост не является точным клоном оригинала (я теряю информацию об авторе, категориях и т. Д., И изображения упоминаются в исходном местоположении), но он показывает, что основная идея работает!