com.nttec.everychan.chans.makaba.MakabaJsonMapper.java Source code

Java tutorial

Introduction

Here is the source code for com.nttec.everychan.chans.makaba.MakabaJsonMapper.java

Source

/*
 * Everychan Android (Meta Imageboard Client)
 * Copyright (C) 2014-2016  miku-nyan <https://github.com/miku-nyan>
 *     
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

package com.nttec.everychan.chans.makaba;

import static com.nttec.everychan.chans.makaba.MakabaConstants.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.nttec.everychan.R;
import com.nttec.everychan.api.models.AttachmentModel;
import com.nttec.everychan.api.models.BadgeIconModel;
import com.nttec.everychan.api.models.BoardModel;
import com.nttec.everychan.api.models.PostModel;
import com.nttec.everychan.api.models.ThreadModel;
import com.nttec.everychan.api.util.RegexUtils;
import com.nttec.everychan.lib.org_json.JSONArray;
import com.nttec.everychan.lib.org_json.JSONException;
import com.nttec.everychan.lib.org_json.JSONObject;

import org.apache.commons.lang3.StringEscapeUtils;

import android.content.res.Resources;

/**
 *  ? JSON- ? 2ch.hk  ? 
 * @author miku-nyan
 *
 */
public class MakabaJsonMapper {
    private static final Pattern ICON_PATTERN = Pattern.compile("<img.+?src=\"(.+?)\".+?(?:title=\"(.+?)\")?.*?/>");

    static BoardModel defaultBoardModel(String boardName, Resources resources) {
        BoardModel model = new BoardModel();
        model.chan = CHAN_NAME;
        model.uniqueAttachmentNames = true;
        model.timeZoneId = "GMT+3";
        model.readonlyBoard = false;
        model.allowDeletePosts = false;
        model.allowDeleteFiles = false;
        model.allowReport = BoardModel.REPORT_WITH_COMMENT;
        model.allowSage = true;
        model.allowEmails = true;
        model.ignoreEmailIfSage = true;
        model.allowCustomMark = true;
        model.allowRandomHash = true;
        model.searchAllowed = true;
        model.catalogAllowed = true;
        model.catalogTypeDescriptions = new String[] { resources.getString(R.string.makaba_catalog_standart),
                resources.getString(R.string.makaba_catalog_last_reply),
                resources.getString(R.string.makaba_catalog_num),
                resources.getString(R.string.makaba_catalog_image_size) };
        model.firstPage = 0;
        model.attachmentsFormatFilters = ATTACHMENT_FORMATS;
        model.markType = BoardModel.MARK_BBCODE;

        model.boardName = boardName;
        model.boardDescription = boardName;
        model.boardCategory = "";

        model.defaultUserName = "?";
        model.bumpLimit = 500;
        model.lastPage = 9;

        model.nsfw = SFW_BOARDS.indexOf(model.boardName) == -1;
        model.requiredFileForNewThread = NO_IMAGES_BOARDS.indexOf(model.boardName) == -1;
        model.attachmentsMaxCount = NO_IMAGES_BOARDS.indexOf(model.boardName) == -1 ? 4 : 0;
        model.allowSubjects = NO_SUBJECTS_BOARDS.indexOf(model.boardName) == -1;
        model.allowNames = NO_USERNAMES_BOARDS.indexOf(model.boardName) == -1;

        return model;
    }

    static BoardModel mapBoardModel(JSONObject source, boolean fromMobileBoardsList, Resources resources)
            throws JSONException {
        BoardModel model = defaultBoardModel(source.getString(fromMobileBoardsList ? "id" : "Board"), resources);

        if (fromMobileBoardsList) {
            model.boardDescription = source.getString("name");
            model.boardCategory = source.getString("category");

            model.defaultUserName = getStringSafe(source, "default_name", "?");
            model.bumpLimit = getIntSafe(source, "bump_limit", 500);
            model.lastPage = getIntSafe(source, "pages", 10) - 1;
        } else {
            model.boardDescription = source.getString("BoardName");
            model.boardCategory = null;

            model.defaultUserName = "?";
            model.bumpLimit = 500;
            try {
                model.lastPage = source.getJSONArray("pages").length() - 1;
            } catch (Exception e) {
                model.lastPage = 9;
            }
        }

        try {
            JSONArray iconsArray = source.getJSONArray("icons");
            if (iconsArray.length() > 0) {
                String[] icons = new String[iconsArray.length() + 1];
                icons[0] = resources.getString(R.string.makaba_no_icon);
                for (int i = 0; i < iconsArray.length(); ++i) {
                    icons[iconsArray.getJSONObject(i).getInt("num")] = iconsArray.getJSONObject(i)
                            .getString("name");
                }
                for (int i = 0; i < icons.length; ++i) {
                    if (icons[i] == null)
                        throw new Exception();
                }
                model.allowIcons = true;
                model.iconDescriptions = icons;
            }
        } catch (Exception e) {
            /*  , ?,  ??   ?,   ?  */ }

        return model;
    }

    static ThreadModel mapThreadModel(JSONObject source, String boardName) throws JSONException {
        ThreadModel model = new ThreadModel();
        model.threadNumber = source.getString("thread_num");
        model.postsCount = source.getInt("posts_count");
        model.attachmentsCount = source.getInt("files_count");
        JSONArray postsArray = source.getJSONArray("posts");
        model.postsCount += postsArray.length();
        model.posts = new PostModel[postsArray.length()];
        for (int i = 0; i < postsArray.length(); ++i) {
            model.posts[i] = mapPostModel(postsArray.getJSONObject(i), boardName);
            if (postsArray.getJSONObject(i).has("files")) {
                model.attachmentsCount += postsArray.getJSONObject(i).getJSONArray("files").length();
            }
        }
        model.isSticky = getIntSafe(postsArray.getJSONObject(0), "sticky", 0) != 0;
        model.isClosed = getIntSafe(postsArray.getJSONObject(0), "closed", 0) != 0;
        return model;
    }

    static PostModel mapPostModel(JSONObject source, String boardName) throws JSONException {
        PostModel model = new PostModel();

        try {
            model.number = source.getString("num");
        } catch (JSONException e) {
            model.number = Long.toString(source.getLong("num"));
        }
        model.name = StringEscapeUtils
                .unescapeHtml4(RegexUtils.removeHtmlSpanTags(getStringSafe(source, "name", "")));
        model.subject = StringEscapeUtils.unescapeHtml4(getStringSafe(source, "subject", ""));
        model.comment = getStringSafe(source, "comment", "");
        model.email = getStringSafe(source, "email", "");
        if (model.email.startsWith("mailto:"))
            model.email = model.email.substring(7);
        model.trip = getStringSafe(source, "trip", "");
        if (model.trip != null) {
            if (model.trip.equals("!!%adm%!!"))
                model.trip = "## Abu ##";
            else if (model.trip.equals("!!%mod%!!"))
                model.trip = "## Mod ##";
            else if (model.trip.equals("!!%Inquisitor%!!"))
                model.trip = "## Applejack ##";
            else if (model.trip.equals("!!%coder%!!"))
                model.trip = "##  ##";
        }
        model.icons = parseIcons(getStringSafe(source, "icon", ""));
        model.op = getIntSafe(source, "op", 0) == 1;
        model.sage = model.email.toLowerCase(Locale.US).contains("sage") || model.name.contains("ID:\u00A0Heaven");
        model.timestamp = source.getLong("timestamp") * 1000;
        model.parentThread = getStringSafe(source, "parent", model.number);
        if (model.parentThread.equals("0"))
            model.parentThread = model.number;

        if (source.has("files")) {
            JSONArray filesArray = source.getJSONArray("files");
            model.attachments = new AttachmentModel[filesArray.length()];
            for (int i = 0; i < filesArray.length(); ++i) {
                model.attachments[i] = mapAttachmentModel(filesArray.getJSONObject(i), boardName);
            }
        } else
            model.attachments = null;

        int banned = getIntSafe(source, "banned", 0);
        switch (banned) {
        case 1:
            model.comment = model.comment
                    + "<br/><em><font color=\"red\">(? ? ?  . ?.)</font></em>";
            break;
        case 2:
            model.comment = model.comment
                    + "<br/><em><font color=\"red\">(? ? ?  .)</font></em>";
            break;
        }

        return model;
    }

    static AttachmentModel mapAttachmentModel(JSONObject source, String boardName) throws JSONException {
        AttachmentModel model = new AttachmentModel();
        try {
            model.size = source.getInt("size");
            model.width = source.getInt("width");
            model.height = source.getInt("height");
            model.thumbnail = fixAttachmentPath(source.getString("thumbnail"), boardName);
            model.path = fixAttachmentPath(source.getString("path"), boardName);
            model.type = AttachmentModel.TYPE_IMAGE_STATIC;
            String pathLower = model.path.toLowerCase(Locale.US);
            if (pathLower.endsWith(".gif"))
                model.type = AttachmentModel.TYPE_IMAGE_GIF;
            else if (pathLower.endsWith(".webm"))
                model.type = AttachmentModel.TYPE_VIDEO;
        } catch (Exception e) {
            if (source.has("path")) {
                model.type = AttachmentModel.TYPE_OTHER_FILE;
                model.path = fixAttachmentPath(source.getString("path"), boardName);
            } else {
                model.type = AttachmentModel.TYPE_OTHER_NOTFILE;
            }
        }
        return model;
    }

    static BadgeIconModel[] parseIcons(String html) {
        if (html == null || html.length() == 0)
            return null;
        Matcher m = ICON_PATTERN.matcher(html);
        List<BadgeIconModel> list = new ArrayList<BadgeIconModel>();
        while (m.find()) {
            BadgeIconModel icon = new BadgeIconModel();
            icon.source = m.group(1);
            icon.description = m.group(2);
            list.add(icon);
        }
        return list.toArray(new BadgeIconModel[list.size()]);
    }

    private static String getStringSafe(JSONObject object, String key, String defaultValue) {
        try {
            return object.getString(key);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    private static int getIntSafe(JSONObject object, String key, int defaultValue) {
        try {
            return object.getInt(key);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    private static String fixAttachmentPath(String url, String boardName) {
        if (url.startsWith("://"))
            return "http" + url;
        if (url.startsWith("/") || url.startsWith("http://") || url.startsWith("https://")) {
            return url;
        }
        return "/".concat(boardName).concat("/").concat(url);
    }
}