Package com.salas.bb.remixfeeds.api

Source Code of com.salas.bb.remixfeeds.api.MetaWeblogAPI

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: MetaWeblogAPI.java,v 1.26 2008/06/26 13:41:57 spyromus Exp $
//

package com.salas.bb.remixfeeds.api;

import com.salas.bb.remixfeeds.prefs.TargetBlog;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.i18n.Strings;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* MetaWeblog API implementation.
*/
abstract class MetaWeblogAPI implements IWeblogAPI
{
    private static final Logger LOG = Logger.getLogger(MetaWeblogAPI.class.getName());

    protected static final String ERR_FAILED_TO_CONTACT = "Failed to connect to the blog API.";
    protected static final String ERR_FAILED_CATEGORIES = "Failed to fetch categories.";
    protected static final String ERR_FAILED_BLOGS = "Failed to fetch blogs.";

    private final String system;

    /**
     * Hidden contructor.
     *
     * @param system the name of blogging system to manage (Wordpress, Movabletype).
     */
    MetaWeblogAPI(String system)
    {
        this.system = system;
    }

    /**
     * Tests connection to blog with the given preferences.
     *
     * @param blog preferences.
     *
     * @return <code>NULL</code> if fine, or error message.
     */
    public String validateBlog(TargetBlog blog)
    {
        if (StringUtils.isEmpty(blog.getApiURL()))
        {
            return Strings.message("ptb.prefs.details.setup.status.nourl");
        }

        String result;

        String apiUser = blog.getUser();
        String apiPassword = blog.getPassword();
        String originalURL = blog.getApiURL();
        String apiURL = StringUtils.fixURL(originalURL);
        if (!apiURL.equals(originalURL)) blog.setApiURL(apiURL);

        try
        {
            URL url = new URL(apiURL);

            result = checkForURL(url, apiUser, apiPassword);
            if (result != null)
            {
                String suggestedURL = suggestURL(url);

                if (suggestedURL != null)
                {
                    url = new URL(suggestedURL);
                    result = checkForURL(url, apiUser, apiPassword);

                    // If success, change the URL specified by user
                    if (result == null) blog.setApiURL(url.toString());
                }
            }
        } catch (MalformedURLException e)
        {
            LOG.log(Level.FINE, ERR_FAILED_CATEGORIES, e);
            result = Strings.message("ptb.prefs.details.setup.status.badurl");
        }

        return result;
    }

    /**
     * Try correcting the URL by adding the default name of the XMLRPC entry point.
     *
     * @param url URL.
     *
     * @return suggestion.
     */
    String suggestURL(URL url)
    {
        String suggestion = null;
        String defaultXMLRPCFile = getDefaultXMLRPCFile();

        if (defaultXMLRPCFile != null)
        {
            String urlS = url.toString();
            if (!urlS.endsWith("/")) urlS += "/";
            suggestion = urlS + defaultXMLRPCFile;
        }

        return suggestion;
    }

    /**
     * Returns the default location of the XMLRPC entry point
     * from root.
     *
     * @return file path.
     */
    protected abstract String getDefaultXMLRPCFile();

    private static String checkForURL(URL apiURL, String apiUser, String apiPassword)
    {
        String msg = null;

        boolean detected;
        try
        {
            XmlRpcClient cl = new XmlRpcClient(apiURL);
            Vector<String> params = new Vector<String>(3);
            params.add("0");
            params.add(apiUser);
            params.add(apiPassword);

            Object res = cl.execute("blogger.getUsersBlogs", params);
            detected = (res instanceof List && ((List)res).size() > 0);
        } catch (IOException e)
        {
            LOG.log(Level.FINE, ERR_FAILED_TO_CONTACT, e);
            detected = false;
        } catch (XmlRpcException e)
        {
            LOG.log(Level.INFO, ERR_FAILED_TO_CONTACT, e);
            msg = e.getMessage();
            if (StringUtils.isEmpty(msg)) msg = null;
            detected = false;
        }

        return detected ? null
            : msg != null ? msg : Strings.message("ptb.prefs.details.setup.status.undetected");
    }


    /**
     * Returns a string representation of the object.
     *
     * @return a string representation of the object.
     */
    public String toString()
    {
        return system;
    }

    // ----------------------------------------------------------------------------------
    // API
    // ----------------------------------------------------------------------------------

    /**
     * Fetches the list of categories.
     *
     * @param blog the blog to query.
     *
     * @return categories.
     */
    public TargetBlog.Category[] getCategories(TargetBlog blog)
    {
        return getCategories(blog, "metaWeblog.getCategories");
    }

    /**
     * Fetches the list of categories.
     *
     * @param blog blog to query.
     * @param apiCall the call.
     *
     * @return categories.
     */
    protected TargetBlog.Category[] getCategories(TargetBlog blog, String apiCall)
    {
        TargetBlog.Category[] categories = null;

        URL url = getApiURL(blog);
        if (url != null)
        {
            XmlRpcClient cl = new XmlRpcClient(url);
            Vector<String> params = new Vector<String>(3);
            params.add(getBlogID(blog));
            params.add(blog.getUser());
            params.add(blog.getPassword());

            try
            {
                Object res = cl.execute(apiCall, params);
                categories = res == null ? null : parseFetchedCategories(res);
            } catch (IOException e)
            {
                LOG.log(Level.FINE, ERR_FAILED_CATEGORIES, e);
            } catch (XmlRpcException e)
            {
                LOG.log(Level.WARNING, ERR_FAILED_CATEGORIES, e);
            }
        }
       
        return categories;
    }

    /**
     * Parses the categories we just fetched from the server into
     * the list of category objects.
     *
     * @param res   the result of the fetch.
     *
     * @return the categories list.
     */
    protected TargetBlog.Category[] parseFetchedCategories(Object res)
    {
        List cats = (List)res;
        TargetBlog.Category[] categories = new TargetBlog.Category[cats.size()];

        for (int i = 0; i < cats.size(); i++)
        {
            Map category = (Map)cats.get(i);
            try
            {
                String id = (String)category.get("categoryId");
                String name = (String)category.get("categoryName");

                categories[i] = new TargetBlog.Category(id, name);
            } catch (NumberFormatException e)
            {
                LOG.log(Level.WARNING, "Skipping category. Invalid ID format.", e);
            }
        }

        return categories;
    }


    /**
     * Fetches the list of all available blogs.
     *
     * @param blog blog preferences.
     *
     * @return categories.
     */
    public TargetBlog.Blog[] getBlogs(TargetBlog blog)
    {
        TargetBlog.Blog[] blogs = null;

        URL url = getApiURL(blog);
        if (url != null)
        {
            XmlRpcClient cl = new XmlRpcClient(url);
            Vector<String> params = new Vector<String>(3);
            params.add(getBlogID(blog));
            params.add(blog.getUser());
            params.add(blog.getPassword());

            try
            {
                List bs = (List)cl.execute("blogger.getUsersBlogs", params);
                if (bs != null)
                {
                    blogs = new TargetBlog.Blog[bs.size()];
                    for (int i = 0; i < bs.size(); i++)
                    {
                        Map b = (Map)bs.get(i);
                        try
                        {
                            String ids = (String)b.get("blogid");
                            String name = (String)b.get("blogName");

                            blogs[i] = new TargetBlog.Blog(ids, name);
                        } catch (NumberFormatException e)
                        {
                            LOG.log(Level.WARNING, "Skipping blog. Invalid ID format.", e);
                        }
                    }
                }
            } catch (IOException e)
            {
                LOG.log(Level.FINE, ERR_FAILED_BLOGS, e);
            } catch (XmlRpcException e)
            {
                LOG.log(Level.WARNING, ERR_FAILED_BLOGS, e);
            }
        }

        return blogs;
    }

    /**
     * Returns ID of the blog from the preferences.
     *
     * @param prefs preferences.
     *
     * @return blog ID or 0.
     */
    protected static String getBlogID(TargetBlog prefs)
    {
        TargetBlog.Blog blog = prefs.getBlog();
        return blog != null ? blog.id : "0";
    }

    /**
     * Creates new post on the blog.
     *
     * @param prefs blog preferences.
     * @param post  post info.
     *
     * @throws WeblogAPIException in case of any problems with posting.
     */
    public void newPost(TargetBlog prefs, WeblogPost post) throws WeblogAPIException
    {
        newPost0(prefs, post);
    }

    /**
     * Creates new post on the blog.
     *
     * @param prefs blog preferences.
     * @param post  post info.
     *
     * @return the results of a call.
     *
     * @throws WeblogAPIException in case of any problems with posting.
     */
    protected Object newPost0(TargetBlog prefs, WeblogPost post)
        throws WeblogAPIException
    {
        Object res;

        URL apiURL = getApiURL(prefs);
        if (apiURL == null) throw new WeblogAPIException("Blog is incorrectly configured.");

        Map<String, Object> content = new Hashtable<String, Object>();
        content.put("title", post.title);
        content.put("description", post.description);
        if (post.sourceURL != null && StringUtils.isNotEmpty(post.sourceTitle))
        {
            content.put("source", source(post.sourceURL, post.sourceTitle));
        }

        // Category names
        String[] catNames = null;
        List<TargetBlog.Category> categories = post.categories;
        if (categories == null)
        {
            TargetBlog.Category catdef = prefs.getDefaultCategory();
            if (catdef != null)
            {
                catNames = new String[] { catdef.name };
            }
        } else
        {
            catNames = new String[categories.size()];
            int i = 0;
            for (TargetBlog.Category c : categories) catNames[i++] = c.name;
        }
        if (catNames != null) content.put("categories", catNames);
        content.put("mt_convert_breaks", "0");

        // Publication date
        if (post.dateCreated != null)
        {
            Calendar now = new GregorianCalendar();

            // Add time to the date
            Calendar local = new GregorianCalendar();
            local.setTime(post.dateCreated);
            local.set(Calendar.HOUR_OF_DAY, now.get(Calendar.HOUR_OF_DAY));
            local.set(Calendar.MINUTE, now.get(Calendar.MINUTE));

            // Adjust time to switch to UTC (GMT)
            // It won't show the timezone in the XMLRPC <dateTime.iso8601> tag and will assume GMT
            // so let's make it GMT.
            TimeZone tz = TimeZone.getDefault();
            local.add(Calendar.MILLISECOND, - (tz.getRawOffset() + tz.getDSTSavings()));

            content.put("date_created_gmt", local.getTime());
            content.put("dateCreated", local.getTime());
        }

        // Excerpt
        if (StringUtils.isNotEmpty(post.excerpt)) content.put("mt_excerpt", post.excerpt.trim());
        setSpecificContentFields(content, post);

        XmlRpcClient cl = new XmlRpcClient(apiURL);
        Vector<Object> params = new Vector<Object>(5);
        params.add(getBlogID(prefs));
        params.add(prefs.getUser());
        params.add(prefs.getPassword());
        params.add(content);
        params.add(post.publish);

        try
        {
            res = cl.execute("metaWeblog.newPost", params);
        } catch (Throwable e)
        {
            throw new WeblogAPIException("Failed to create a post.", e);
        }

        return res;
    }

    /**
     * API-dependent content settings.
     *
     * @param content   content.
     * @param post      post info.
     */
    protected void setSpecificContentFields(Map<String, Object> content, WeblogPost post)
    {
        content.put("mt_allow_comments", post.allowComments ? "1" : "0");
        content.put("mt_allow_pings", post.allowTrackbacks ? "1" : "0");
    }

    /**
     * Creates source array.
     *
     * @param sourceURL     source URL.
     * @param sourceTitle   source title.
     *
     * @return source element.
     */
    private static Map<String, String> source(URL sourceURL, String sourceTitle)
    {
        Map<String, String> source = new Hashtable<String, String>();
        source.put("url", sourceURL.toString());
        source.put("name", sourceTitle);

        return source;
    }

    /**
     * Returns API URL or <code>NULL</code> if URL isn't valid.
     *
     * @param prefs preferences.
     *
     * @return API URL or <code>NULL</code>.
     */
    protected static URL getApiURL(TargetBlog prefs)
    {
        URL url;

        try
        {
            url = new URL(prefs.getApiURL());
        } catch (MalformedURLException e)
        {
            url = null;
        }

        return url;
    }

    /**
     * Returns TRUE if the API URL field is not applicable to this weblog API.
     *
     * @return TRUE if not applicable.
     */
    public boolean isApiUrlApplicable()
    {
        return true;
    }
}
TOP

Related Classes of com.salas.bb.remixfeeds.api.MetaWeblogAPI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.