package org.wordpress.android.ui.accounts;
import android.content.Context;
import android.support.annotation.NonNull;
import android.text.Editable;
import org.wordpress.android.WordPress;
import org.wordpress.android.models.Blog;
import org.wordpress.android.ui.stats.datasets.StatsTable;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.MapUtils;
import org.wordpress.android.util.StringUtils;
import org.wordpress.android.util.UrlUtils;
import org.wordpress.android.util.WPUrlUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public class BlogUtils {
private static final String DEFAULT_IMAGE_SIZE = "2000";
public static final int BLOG_ID_INVALID = 0;
/**
* Remove blogs that are not in the list and add others
* TODO: it's horribly slow due to datastructures used (List of Map), We should replace
* that by a HashSet of a specialized Blog class (that supports comparison)
*
* @return true if a change has been made (new blog added, old blog updated, blog deleted).
*/
public static boolean syncBlogs(Context context, List<Map<String, Object>> newBlogList, String username) {
boolean retValue;
// Add all blogs from blogList
retValue = addBlogs(newBlogList, username);
// Delete blogs if not in blogList
List<Map<String, Object>> allBlogs = WordPress.wpDB.getBlogsBy("dotcomFlag=1", null);
Set<String> newBlogURLs = new HashSet<String>();
for (Map<String, Object> blog : newBlogList) {
newBlogURLs.add(blog.get("xmlrpc").toString() + blog.get("blogid").toString());
}
for (Map<String, Object> blog : allBlogs) {
if (!newBlogURLs.contains(blog.get("url").toString() + blog.get("blogId"))) {
WordPress.wpDB.deleteBlog(context, Integer.parseInt(blog.get("id").toString()));
StatsTable.deleteStatsForBlog(context, Integer.parseInt(blog.get("id").toString())); // Remove stats data
retValue = true;
}
}
return retValue;
}
/**
* Add selected blog(s) to the database.
*
* @return true if a change has been made (new blog added or old blog updated).
*/
public static boolean addBlogs(List<Map<String, Object>> blogList, String username, String password,
String httpUsername, String httpPassword) {
boolean retValue = false;
for (Map<String, Object> blogMap : blogList) {
String blogName = StringUtils.unescapeHTML(blogMap.get("blogName").toString());
String xmlrpc = blogMap.get("xmlrpc").toString();
String homeUrl = blogMap.get("url").toString();
String blogId = blogMap.get("blogid").toString();
boolean isVisible = true;
if (blogMap.containsKey("isVisible")) {
isVisible = MapUtils.getMapBool(blogMap, "isVisible");
}
boolean isAdmin = MapUtils.getMapBool(blogMap, "isAdmin");
long planID = 0;
if (blogMap.containsKey("planID")) {
planID = MapUtils.getMapLong(blogMap, "planID");
}
String planShortName = MapUtils.getMapStr(blogMap, "plan_product_name_short");
String capabilities = MapUtils.getMapStr(blogMap, "capabilities");
retValue |= addOrUpdateBlog(blogName, xmlrpc, homeUrl, blogId, username, password, httpUsername,
httpPassword, isAdmin, isVisible, planID, planShortName, capabilities);
}
return retValue;
}
/**
* Check xmlrpc urls validity
*
* @param blogList blog list
* @return true if there is at least one invalid xmlrpc url
*/
public static boolean isAnyInvalidXmlrpcUrl(List<Map<String, Object>> blogList) {
for (Map<String, Object> blogMap : blogList) {
String xmlrpc = blogMap.get("xmlrpc").toString();
if (!UrlUtils.isValidUrlAndHostNotNull(xmlrpc)) {
return true;
}
}
return false;
}
/**
* Add a new blog or update a blog name in local DB.
*
* @return true if a new blog has been added or an old blog has been updated.
* Return false if no change has been made.
*/
public static boolean addOrUpdateBlog(String blogName, String xmlRpcUrl, String homeUrl, String blogId,
String username, String password, String httpUsername, String httpPassword,
boolean isAdmin, boolean isVisible,
long planID, String planShortName, String capabilities) {
Blog blog;
if (!WordPress.wpDB.isBlogInDatabase(Integer.parseInt(blogId), xmlRpcUrl)) {
// The blog isn't in the app, so let's create it
blog = new Blog(xmlRpcUrl, username, password);
blog.setHomeURL(homeUrl);
blog.setHttpuser(httpUsername);
blog.setHttppassword(httpPassword);
blog.setBlogName(blogName);
// deprecated
blog.setImagePlacement("");
blog.setFullSizeImage(false);
blog.setMaxImageWidth(DEFAULT_IMAGE_SIZE);
// deprecated
blog.setMaxImageWidthId(0);
blog.setRemoteBlogId(Integer.parseInt(blogId));
blog.setDotcomFlag(WPUrlUtils.isWordPressCom(xmlRpcUrl));
// assigned later in getOptions call
blog.setWpVersion("");
blog.setAdmin(isAdmin);
blog.setHidden(!isVisible);
blog.setPlanID(planID);
blog.setPlanShortName(planShortName);
blog.setCapabilities(capabilities);
WordPress.wpDB.saveBlog(blog);
return true;
} else {
// Update blog name and/or PlanID/PlanShortName
int localTableBlogId = WordPress.wpDB.getLocalTableBlogIdForRemoteBlogIdAndXmlRpcUrl(
Integer.parseInt(blogId), xmlRpcUrl);
try {
boolean blogUpdated = false;
blog = WordPress.wpDB.instantiateBlogByLocalId(localTableBlogId);
if (!blogName.equals(blog.getBlogName())) {
blog.setBlogName(blogName);
blogUpdated = true;
}
if (planID != blog.getPlanID()) {
blog.setPlanID(planID);
blogUpdated = true;
}
if (!blog.getPlanShortName().equals(planShortName)) {
blog.setPlanShortName(planShortName);
blogUpdated = true;
}
if (blog.getCapabilities() == null || !blog.getCapabilities().equals(capabilities)) {
blog.setCapabilities(capabilities);
blogUpdated = true;
}
if (blogUpdated) {
WordPress.wpDB.saveBlog(blog);
return true;
}
} catch (Exception e) {
AppLog.e(T.NUX, "localTableBlogId: " + localTableBlogId + " not found");
}
return false;
}
}
public static boolean addBlogs(List<Map<String, Object>> userBlogList, String username) {
return addBlogs(userBlogList, username, null, null, null);
}
/**
* Get a Blog's local Id.
*
* @param blog The Blog to get its local ID
* @return Blog's local id or {@value BlogUtils#BLOG_ID_INVALID} if null
*/
public static int getBlogLocalId(final Blog blog) {
return (blog != null ? blog.getLocalTableBlogId() : BLOG_ID_INVALID);
}
public static void convertToLowercase(Editable s) {
String lowerCase = s.toString().toLowerCase();
if (!lowerCase.equals(s.toString())) {
s.replace(0, s.length(), lowerCase);
}
}
@NonNull
public static Set<String> planTags() {
String[] extraFields = {"plan_product_id"};
List<Map<String, Object>> blogs = WordPress.wpDB.getBlogsBy("dotcomFlag=1", extraFields);
Set<String> tags = new HashSet<>();
for (Map<String, Object> blog : blogs) {
int planId = MapUtils.getMapInt(blog, "plan_product_id");
if (planId == 0) {
// Skip unknown plans, MapUtils will turn any missing plan ID into 0
continue;
}
String tag = String.format(Locale.US, "plan:%d", planId);
tags.add(tag);
}
return tags;
}
}