net.longfalcon.web.ApiController.java Source code

Java tutorial

Introduction

Here is the source code for net.longfalcon.web.ApiController.java

Source

/*
 * Copyright (c) 2016. Sten Martinez
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package net.longfalcon.web;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.longfalcon.newsj.model.Category;
import net.longfalcon.newsj.model.Release;
import net.longfalcon.newsj.model.Site;
import net.longfalcon.newsj.model.User;
import net.longfalcon.newsj.persistence.CategoryDAO;
import net.longfalcon.newsj.persistence.ReleaseDAO;
import net.longfalcon.newsj.persistence.SiteDAO;
import net.longfalcon.newsj.persistence.UserDAO;
import net.longfalcon.newsj.persistence.UserExCatDAO;
import net.longfalcon.newsj.service.SearchService;
import net.longfalcon.newsj.service.SiteService;
import net.longfalcon.newsj.service.UserService;
import net.longfalcon.newsj.util.ValidatorUtil;
import net.longfalcon.newsj.ws.newznab.ApiResponse;
import net.longfalcon.newsj.ws.newznab.CapsType;
import net.longfalcon.newsj.ws.newznab.Error;
import net.longfalcon.newsj.ws.newznab.RegisterType;
import net.longfalcon.newsj.ws.newznab.caps.CategoriesType;
import net.longfalcon.newsj.ws.newznab.caps.CategoryType;
import net.longfalcon.newsj.ws.newznab.caps.LimitsType;
import net.longfalcon.newsj.ws.newznab.caps.RegistrationType;
import net.longfalcon.newsj.ws.newznab.caps.SearchingType;
import net.longfalcon.newsj.ws.newznab.caps.ServerType;
import net.longfalcon.newsj.ws.newznab.caps.SubCatType;
import net.longfalcon.view.UserRegistrationVO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.ArrayList;
import java.util.List;

/**
 * User: longfalcon
 * Date: 3/1/16
 */
@Controller
public class ApiController {

    @Autowired
    CategoryDAO categoryDAO;

    @Autowired
    ReleaseDAO releaseDAO;

    @Autowired
    SearchService searchService;

    @Autowired
    SiteDAO siteDAO;

    @Autowired
    UserExCatDAO userExCatDAO;

    @Autowired
    UserService userService;

    @Autowired
    UserDAO userDAO;

    private static final String TYPE_DETAILS = "d";
    private static final String TYPE_GET = "g";
    private static final String TYPE_SEARCH = "s";
    private static final String TYPE_CAPS = "c";
    private static final String TYPE_TVSEARCH = "tv";
    private static final String TYPE_MOVIE = "m";
    private static final String TYPE_REGISTER = "r";
    private static final Log _log = LogFactory.getLog(ApiController.class);

    @RequestMapping(value = "/api", produces = "text/xml")
    @ResponseBody
    public ApiResponse xmlApi(@RequestParam(value = "t", required = false) String type,
            @RequestParam(value = "apikey", required = false) String apiKey,
            @RequestParam(value = "id", required = false) String guid,
            @RequestParam(value = "extended", required = false) String extended,
            @RequestParam(value = "del", required = false) String del,
            @RequestParam(value = "q", required = false) String query,
            @RequestParam(value = "maxage", required = false) String maxAge,
            @RequestParam(value = "limit", required = false) String limit,
            @RequestParam(value = "offset", required = false) String offset,
            @RequestParam(value = "imdbid", required = false) String imdbId,
            @RequestParam(value = "rid", required = false) String rid,
            @RequestParam(value = "season", required = false) String season,
            @RequestParam(value = "ep", required = false) String ep,
            @RequestParam(value = "email", required = false) String email,
            @RequestParam(value = "cat", required = false) String categoryIdsString,
            UriComponentsBuilder uriComponentsBuilder) {
        String function = TYPE_SEARCH;
        if (ValidatorUtil.isNotNull(type)) {
            if (type.equals("details") || type.equals(TYPE_DETAILS)) {
                function = TYPE_DETAILS;
            } else if (type.equals("get") || type.equals(TYPE_GET)) {
                function = TYPE_GET;
            } else if (type.equals("search") || type.equals(TYPE_SEARCH)) {
                function = TYPE_SEARCH;
            } else if (type.equals("caps") || type.equals(TYPE_CAPS)) {
                function = TYPE_CAPS;
            } else if (type.equals("tvsearch") || type.equals(TYPE_TVSEARCH)) {
                function = TYPE_TVSEARCH;
            } else if (type.equals("movie") || type.equals(TYPE_MOVIE)) {
                function = TYPE_MOVIE;
            } else if (type.equals("register") || type.equals(TYPE_REGISTER)) {
                function = TYPE_REGISTER;
            } else {
                return generateError(202);
            }
        } else {
            return generateError(200);
        }

        String serverBaseUrl = uriComponentsBuilder.toUriString();

        if (function.equals(TYPE_CAPS)) {
            return getCaps(serverBaseUrl);
        }

        if (function.equals(TYPE_REGISTER)) {
            return getRegister(email);

        }

        if (ValidatorUtil.isNull(apiKey)) {
            return generateError(200);
        }

        User user = userDAO.findByApiKey(apiKey);
        if (user == null) {
            return generateError(100);
        }

        if (function.equals(TYPE_SEARCH)) {
            if (query != null && query.equals("")) {
                return generateError(200);
            }
            return getSearchResponse(user, serverBaseUrl, extended, query, maxAge, limit, offset,
                    categoryIdsString);
        }

        if (function.equals(TYPE_TVSEARCH)) {
            if (query != null && query.equals("")) {
                return generateError(200);
            }
            return getTvSearchResponse(user, serverBaseUrl, extended, query, maxAge, limit, offset,
                    categoryIdsString, rid, season, ep);
        }

        if (function.equals(TYPE_MOVIE)) {
            if (query != null && query.equals("")) {
                return generateError(200);
            }
            return getMovieSearchResponse(user, serverBaseUrl, extended, query, maxAge, limit, offset,
                    categoryIdsString, imdbId);
        }

        if (function.equals(TYPE_DETAILS)) {
            return getReleaseDetailsResponse(user, serverBaseUrl, extended, guid);
        }

        return generateError(202);
    }

    @RequestMapping(value = "/api", produces = "application/x-nzb", params = "t=g")
    public RedirectView getNzbApi(@RequestParam(value = "id", required = true) String guid,
            @RequestParam(value = "del", required = false) String del) {
        return new RedirectView("/getnzb/" + guid + ".nzb", true);
    }

    @RequestMapping(value = "/api", params = "o=json", produces = "application/json")
    @ResponseBody
    public String jsonApi(@RequestParam(value = "t", required = false) String type,
            @RequestParam(value = "apikey", required = false) String apiKey,
            @RequestParam(value = "id", required = false) String guid,
            @RequestParam(value = "extended", required = false) String extended,
            @RequestParam(value = "del", required = false) String del,
            @RequestParam(value = "q", required = false) String query,
            @RequestParam(value = "maxage", required = false) String maxAge,
            @RequestParam(value = "limit", required = false) String limit,
            @RequestParam(value = "offset", required = false) String offset,
            @RequestParam(value = "imdbid", required = false) String imdbId,
            @RequestParam(value = "rid", required = false) String rid,
            @RequestParam(value = "season", required = false) String season,
            @RequestParam(value = "ep", required = false) String ep,
            @RequestParam(value = "email", required = false) String email,
            @RequestParam(value = "cat", required = false) String categoryIdsString,
            UriComponentsBuilder uriComponentsBuilder) throws JsonProcessingException {

        ApiResponse apiResponse = xmlApi(type, apiKey, guid, extended, del, query, maxAge, limit, offset, imdbId,
                rid, season, ep, email, categoryIdsString, uriComponentsBuilder);

        ObjectMapper objectMapper = new ObjectMapper();

        return objectMapper.writeValueAsString(apiResponse);
    }

    private ApiResponse getRegister(String email) {
        Site site = siteDAO.getDefaultSite();
        if (ValidatorUtil.isNull(email)) {
            return generateError(200);
        }

        if (site.getRegisterStatus() != SiteService.REGISTER_STATUS_OPEN) {
            return generateError(104);
        }

        if (!ValidatorUtil.isValidEmail(email)) {
            return generateError(106);
        }

        User user = userDAO.findByEmail(email);
        if (user != null) {
            return generateError(105);
        }

        String username = userService.generateUsername(email);
        String password = userService.generatePassword();

        UserRegistrationVO userRegistrationVO = new UserRegistrationVO();
        userRegistrationVO.setEmail(email);
        userRegistrationVO.setUserName(username);
        userRegistrationVO.setPassword(password);
        long returnCode = userService.signup(userRegistrationVO);

        if (returnCode < 0) {
            return generateError(107);
        }

        user = userDAO.findByUserId(returnCode);
        if (user == null) {
            return generateError(107);
        }

        return new RegisterType(username, password, user.getRssToken());
    }

    private ApiResponse getCaps(String serverBaseUrl) {
        Site site = siteDAO.getDefaultSite();

        CapsType caps = new CapsType();
        caps.setServerType(new ServerType("0.2.3", "0.1", site.getTitle(), site.getStrapLine(), "email@email.com",
                serverBaseUrl, ""));
        caps.setLimitsType(new LimitsType(100, 100));
        caps.setRegistrationType(new RegistrationType(true, site.getRegisterStatus() == 1));
        caps.setSearchingType(new SearchingType(true, true, true, false));
        List<CategoryType> categoryTypes = new ArrayList<>();
        List<Category> parentCategories = categoryDAO.getParentCategories();
        for (Category parentCategory : parentCategories) {
            List<Category> subCategories = categoryDAO.findByParentId(parentCategory.getId());
            List<SubCatType> subCatTypes = new ArrayList<>();
            for (Category category : subCategories) {
                SubCatType subCatType = new SubCatType(category.getId(), category.getTitle());
                subCatTypes.add(subCatType);
            }
            CategoryType categoryType = new CategoryType(parentCategory.getId(), parentCategory.getTitle(),
                    subCatTypes);
            categoryTypes.add(categoryType);
        }
        CategoriesType categoriesType = new CategoriesType(categoryTypes);
        caps.setCategoriesType(categoriesType);

        return caps;
    }

    private ApiResponse getSearchResponse(User user, String serverBaseUrl, String extended, String query,
            String maxAge, String limitString, String offsetString, String categoryIdsString) {

        List<Integer> categoryIds = new ArrayList<>();
        if (ValidatorUtil.isNotNull(categoryIdsString)) {
            String[] categoryIdsSplit = categoryIdsString.split(",");
            for (String categoryIdString : categoryIdsSplit) {
                categoryIds.add(Integer.parseInt(categoryIdString));
            }
        }
        int maxAgeDays = -1;
        if (ValidatorUtil.isNotNull(maxAge)) {
            if (ValidatorUtil.isNumeric(maxAge)) {
                maxAgeDays = Integer.parseInt(maxAge);
            } else {
                return generateError(200);
            }
        }
        List<Integer> userExCatIds = userExCatDAO.getUserExCatIds(user.getId());
        long groupId = -1;
        String orderByFieldName = "addDate";
        boolean orderByDesc = true;
        int offset = 0;
        if (ValidatorUtil.isNotNull(offsetString)) {
            offset = Integer.parseInt(offsetString);
        }
        int pageSize = 100;
        if (ValidatorUtil.isNotNull(limitString)) {
            pageSize = Integer.parseInt(limitString);
        }
        boolean isExtended = false;
        if (ValidatorUtil.isNotNull(extended)) {
            isExtended = extended.equals("1") || extended.equals("true");
        }

        return searchService.searchReleasesApi(user, serverBaseUrl, query, categoryIds, maxAgeDays, userExCatIds,
                groupId, orderByFieldName, orderByDesc, offset, pageSize, isExtended);
    }

    private ApiResponse getTvSearchResponse(User user, String serverBaseUrl, String extended, String query,
            String maxAge, String limitString, String offsetString, String categoryIdsString, String rageIdString,
            String season, String episode) {

        List<Integer> categoryIds = new ArrayList<>();
        if (ValidatorUtil.isNotNull(categoryIdsString)) {
            String[] categoryIdsSplit = categoryIdsString.split(",");
            for (String categoryIdString : categoryIdsSplit) {
                categoryIds.add(Integer.parseInt(categoryIdString));
            }
        }
        int maxAgeDays = -1;
        if (ValidatorUtil.isNotNull(maxAge)) {
            if (ValidatorUtil.isNumeric(maxAge)) {
                maxAgeDays = Integer.parseInt(maxAge);
            } else {
                return generateError(200);
            }
        }
        List<Integer> userExCatIds = userExCatDAO.getUserExCatIds(user.getId());
        long groupId = -1;
        String orderByFieldName = "addDate";
        boolean orderByDesc = true;
        int offset = 0;
        if (ValidatorUtil.isNotNull(offsetString)) {
            offset = Integer.parseInt(offsetString);
        }
        int pageSize = 100;
        if (ValidatorUtil.isNotNull(limitString)) {
            pageSize = Integer.parseInt(limitString);
        }
        boolean isExtended = false;
        if (ValidatorUtil.isNotNull(extended)) {
            isExtended = extended.equals("1") || extended.equals("true");
        }

        long rageId = -1; // this is a TVRage metadata ID, not a tvInfo id
        if (ValidatorUtil.isNotNull(rageIdString)) {
            rageId = Long.parseLong(rageIdString);
        }

        return searchService.searchTvReleasesApi(user, serverBaseUrl, query, rageId, season, episode, categoryIds,
                maxAgeDays, userExCatIds, groupId, orderByFieldName, orderByDesc, offset, pageSize, isExtended);
    }

    private ApiResponse getMovieSearchResponse(User user, String serverBaseUrl, String extended, String query,
            String maxAge, String limitString, String offsetString, String categoryIdsString, String imdbIdString) {

        List<Integer> categoryIds = new ArrayList<>();
        if (ValidatorUtil.isNotNull(categoryIdsString)) {
            String[] categoryIdsSplit = categoryIdsString.split(",");
            for (String categoryIdString : categoryIdsSplit) {
                categoryIds.add(Integer.parseInt(categoryIdString));
            }
        }
        int maxAgeDays = -1;
        if (ValidatorUtil.isNotNull(maxAge)) {
            if (ValidatorUtil.isNumeric(maxAge)) {
                maxAgeDays = Integer.parseInt(maxAge);
            } else {
                return generateError(200);
            }
        }
        List<Integer> userExCatIds = userExCatDAO.getUserExCatIds(user.getId());
        long groupId = -1;
        String orderByFieldName = "addDate";
        boolean orderByDesc = true;
        int offset = 0;
        if (ValidatorUtil.isNotNull(offsetString)) {
            offset = Integer.parseInt(offsetString);
        }
        int pageSize = 100;
        if (ValidatorUtil.isNotNull(limitString)) {
            pageSize = Integer.parseInt(limitString);
        }
        boolean isExtended = false;
        if (ValidatorUtil.isNotNull(extended)) {
            isExtended = extended.equals("1") || extended.equals("true");
        }

        long imdbId = -1;
        if (ValidatorUtil.isNotNull(imdbIdString)) {
            imdbId = Long.parseLong(imdbIdString);
        }

        return searchService.searchMovieReleasesApi(user, serverBaseUrl, query, imdbId, categoryIds, maxAgeDays,
                userExCatIds, groupId, orderByFieldName, orderByDesc, offset, pageSize, isExtended);
    }

    private ApiResponse getReleaseDetailsResponse(User user, String serverBaseUrl, String extended, String guid) {
        boolean isExtended = false;
        if (ValidatorUtil.isNotNull(extended)) {
            isExtended = extended.equals("1") || extended.equals("true");
        }

        Release release = releaseDAO.findByGuid(guid);
        if (release == null) {
            return generateError(300);
        } else {
            return searchService.getSingleRelease(user, serverBaseUrl, release, isExtended);
        }
    }

    // todo: replace with enum
    private Error generateError(int code) {

        String errorMessage;
        switch (code) {
        case 100:
            errorMessage = "Incorrect user credentials";
            break;
        case 101:
            errorMessage = "Account suspended";
            break;
        case 102:
            errorMessage = "Insufficient privileges/not authorized";
            break;
        case 103:
            errorMessage = "Registration denied";
            break;
        case 104:
            errorMessage = "Registrations are closed";
            break;
        case 105:
            errorMessage = "Invalid registration (Email Address Taken)";
            break;
        case 106:
            errorMessage = "Invalid registration (Email Address Bad Format)";
            break;
        case 107:
            errorMessage = "Registration Failed (Data error)";
            break;
        case 200:
            errorMessage = "Missing parameter";
            break;
        case 201:
            errorMessage = "Incorrect parameter";
            break;
        case 202:
            errorMessage = "No such function";
            break;
        case 203:
            errorMessage = "Function not available";
            break;
        case 300:
            errorMessage = "No such item";
            break;
        default:
            errorMessage = "Unknown error";
            break;
        }

        return new Error(code, errorMessage);
    }
}