net.fluxo.dd.FluxoWSProcess.java Source code

Java tutorial

Introduction

Here is the source code for net.fluxo.dd.FluxoWSProcess.java

Source

/*
 * FluxoWSProcess.java
 *
 * Copyright (c) 2014 Ronald Kurniawan. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package net.fluxo.dd;

import net.fluxo.dd.dbo.Task;
import net.fluxo.plugins.kas.TrKas;
import net.fluxo.plugins.tpb.TrTPB;
import net.xeoh.plugins.base.PluginManager;
import org.apache.commons.codec.net.URLCodec;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;

/**
 * This class contains REST methods that are served via the embedded Jetty server.
 * <p>Each of these methods has one counterpart that can be called via an XMPP message.</p>
 *
 * @author Ronald Kurniawan (viper)
 * @version 0.4.5, 11/04/14
 */
@Path("/ws")
public class FluxoWSProcess {

    /**
     * This method should return a HTTP/200 and a string ("FLUXO-REST-WS") when called.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/ping</p>
     *
     * @return a {@link javax.ws.rs.core.Response} object signifying that the server is alive and responding.
     */
    @GET
    @Path("/ping")
    @Produces("text/plain")
    public Response test() {
        return Response.status(200).entity("FLUXO-REST-WS").build();
    }

    /**
     * Return a JSON object containing the list of movies available on YIFY site, newest to oldest.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/ylist/page/[page]/quality/[quality]/rating/[rating]</p>
     *
     * @param page    page number to serve (starts from 1)
     * @param quality movie quality to display (0: all movies; 1: 720p movies only; 2: 1080p movies only; 3: 3D movies only)
     * @param rating  IMDB rating to filter the list; starts from 0, which displays all movies all through to 9
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object of movie list
     */
    @GET
    @Path("/ylist/page/{page}/quality/{quality}/rating/{rating}")
    @Produces("application/json")
    public Response getYIFYList(@PathParam("page") int page, @PathParam("quality") int quality,
            @PathParam("rating") int rating) {
        try {
            String response = YIFYP.procListMovie(page, quality, rating, OUtils.ExternalIP(),
                    OUtils.readConfig().HTTPPort());
            return Response.status(200).entity(response).build();
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
    }

    /**
     * Return a JSON object containing the details of a particular movie.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/ydetails/[movie-id]</p>
     *
     * @param id the id of the movie
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object of the movie details
     */
    @GET
    @Path("/ydetails/{id}")
    @Produces("application/json")
    public Response getYIFYMovieDetails(@PathParam("id") int id) {
        try {
            String response = YIFYP.procMovieDetails(id, OUtils.ExternalIP(), OUtils.readConfig().HTTPPort());
            return Response.status(200).entity(response).build();
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
    }

    /**
     * Return a JSON object containing the results of a search on YIFY site.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/ysearch?st=[search-term]</p>
     *
     * @param search the search term, could be title or part of title of the movie(s)
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object of the search results
     */
    @GET
    @Path("/ysearch")
    @Produces("application/json")
    public Response getYIFYSearchResult(@DefaultValue("") @QueryParam("st") String search) {
        try {
            if (search.length() > 0) {
                String decodedTerm = (new URLCodec()).decode(search);
                String response = YIFYP.procYIFYSearch(decodedTerm);
                return Response.status(200).entity(response).build();
            }
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
        return Response.status(400).entity("NO-SEARCH-TERM").build();
    }

    /**
     * Returns the status of the downloads for a particular user.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/status/[user-id]</p>
     *
     * @param userID the user ID to query
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object with list of current downloads for
     * a particular user
     */
    @GET
    @Path("/status/{id}")
    @Produces("application/json")
    public Response getDownloadStatus(@Context HttpServletRequest htRequest, @PathParam("id") String userID) {
        String username = htRequest.getHeader("DDUSER");
        String password = htRequest.getHeader("DDPWD");
        if (username == null || password == null || !DbControl.authCredentials(username, password)) {
            return Response.status(400).entity("NOT-AUTHORIZED").build();
        }
        try {
            Task[] arrTasks = DbControl.queryTasks(userID);
            HashMap<String, String> progressMap = new HashMap<>();
            for (Task t : arrTasks) {
                int progress = -1;
                if (t.TaskCompletedLength() > 0 && t.TaskTotalLength() > 0) {
                    progress = (int) ((t.TaskCompletedLength() * 100) / t.TaskTotalLength());
                }
                String dlName = "Unknown Download";
                if (t.TaskPackage().nonEmpty()) {
                    dlName = t.TaskPackage().get();
                }
                progressMap.put(dlName, String.valueOf(progress));
            }
            String response = OUtils.DownloadProgressToJson(progressMap);
            return Response.status(200).entity(response).build();
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
    }

    /**
     * Add a bittorrent URL to current list of downloads for the server to process.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/addtorrent/[user-id]/[torrent-url]</p>
     *
     * @param htRequest  a HttpServletRequest object
     * @param uri   bittorrent magnet url or http torrent url to download
     * @param owner user ID associated with this download
     * @return a string containing the status of the request; "OK" followed by download ID or an error message
     */
    @GET
    @Path("/addtorrent/{owner}/{uri}")
    @Produces("text/plain")
    public Response getTorrentUrl(@Context HttpServletRequest htRequest,
            @DefaultValue("") @PathParam("uri") String uri, @DefaultValue("") @PathParam("owner") String owner) {
        String username = htRequest.getHeader("DDUSER");
        String password = htRequest.getHeader("DDPWD");
        if (username == null || password == null || !DbControl.authCredentials(username, password)) {
            return Response.status(400).entity("NOT-AUTHORIZED").build();
        }
        try {
            if (uri.length() > 0 && owner.length() > 0) {
                String decodedURL = URLDecoder.decode(uri, "UTF-8");
                String response = OAria.processRequest(decodedURL, owner, false, "", "");
                return Response.status(200).entity(response).build();
            }
        } catch (UnsupportedEncodingException uee) {
            return Response.status(500).entity(uee.getMessage()).build();
        }
        return Response.status(400).entity("EITHER-URI-ERROR-OR-NO-OWNER").build();
    }

    /**
     * Add a video site URL to current list of downloads for the server to process.
     * @param htRequest a HttpServletRequest object
     * @param uri video URL from a supported video sharing website
     * @param owner user ID associated with this download
     * @return a string containing the status of the request; "OK" followed by download ID or an error message
     */
    @GET
    @Path("/addvid/{owner}/{uri}")
    @Produces("text/plain")
    public Response addNewVideoDownload(@Context HttpServletRequest htRequest,
            @DefaultValue("") @PathParam("uri") String uri, @DefaultValue("") @PathParam("owner") String owner) {
        String username = htRequest.getHeader("DDUSER");
        String password = htRequest.getHeader("DDPWD");
        if (username == null || password == null || !DbControl.authCredentials(username, password)) {
            return Response.status(400).entity("NOT-AUTHORIZED").build();
        }
        try {
            if (uri.length() > 0 && owner.length() > 0) {
                String decodedURL = URLDecoder.decode(uri, "UTF-8");
                String response = OVideoP.processRequest(decodedURL, owner);
                return Response.status(200).entity(response).build();
            }
        } catch (UnsupportedEncodingException uee) {
            return Response.status(500).entity(uee.getMessage()).build();
        }
        return Response.status(400).entity("EITHER-URI-ERROR-OR-NO-OWNER").build();
    }

    /**
     * Add a HTTP-based download to current list of downloads for the server to process.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/adduri/[user-id]/[http-url]</p>
     *
     * @param uri   HTTP download url
     * @param owner user ID associated with this download
     * @return a string containing the status of the request; "OK" followed by download ID or an error message
     */
    @GET
    @Path("/adduri/{owner}/{uri}")
    @Produces("text/plain")
    public Response getHttpUrl(@Context HttpServletRequest htRequest,
            @DefaultValue("") @PathParam("uri") String uri, @DefaultValue("") @PathParam("owner") String owner) {
        String username = htRequest.getHeader("DDUSER");
        String password = htRequest.getHeader("DDPWD");
        if (username == null || password == null || !DbControl.authCredentials(username, password)) {
            return Response.status(400).entity("NOT-AUTHORIZED").build();
        }
        try {
            if (uri.length() > 0 && owner.length() > 0) {
                String decodedURL = URLDecoder.decode(uri, "UTF-8");
                String response = OAria.processRequest(decodedURL, owner, true, "", "");
                return Response.status(200).entity(response).build();
            }
        } catch (UnsupportedEncodingException uee) {
            return Response.status(500).entity(uee.getMessage()).build();
        }
        return Response.status(400).entity("EITHER-URI-ERROR-OR-NO-OWNER").build();
    }

    /**
     * Add a HTTP-based download to current list of downloads for the server to process, with authentication (username
     * and password).
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/adduric/[user-id]/[username]/[password]/[http-url]</p>
     *
     * @param uri      HTTP download url
     * @param owner    user ID associated with this download
     * @param username username for authentication
     * @param password password for authentication
     * @return a string containing the status of the request; "OK" followed by download ID or an error message
     */
    @GET
    @Path("/adduric/{owner}/{username}/{password}/{uri}")
    @Produces("text/plain")
    public Response getHttpUrlC(@Context HttpServletRequest htRequest,
            @DefaultValue("") @PathParam("uri") String uri, @DefaultValue("") @PathParam("owner") String owner,
            @DefaultValue("") @PathParam("username") String username,
            @DefaultValue("") @PathParam("password") String password) {
        String credUsername = htRequest.getHeader("DDUSER");
        String credPassword = htRequest.getHeader("DDPWD");
        if (credUsername == null || credPassword == null
                || !DbControl.authCredentials(credUsername, credPassword)) {
            return Response.status(400).entity("NOT-AUTHORIZED").build();
        }
        try {
            if (uri.length() > 0 && owner.length() > 0 && username.length() > 0 && password.length() > 0) {
                String decodedURL = URLDecoder.decode(uri, "UTF-8");
                String response = OAria.processRequest(decodedURL, owner, true, username, password);
                return Response.status(200).entity(response).build();
            }
        } catch (UnsupportedEncodingException uee) {
            return Response.status(500).entity(uee.getMessage()).build();
        }
        return Response.status(400).entity("EITHER-URI-ERROR-OR-NO-OWNER-OR-USERNAME-PASSWORD-ERROR").build();
    }

    /**
     * Return a JSON object containing the list of search results from a certain notorius torrent site.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/tpb/[search-term]/[page]/[categories]</p>
     *
     * @param searchTerm the search term
     * @param page       page number to page number to serve (starts from 0)
     * @param cats       list of category number, separated by commas
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object with search results from a notorious
     * torrents site
     */
    @GET
    @Path("/tpb/{st}/{page}/{cat}")
    @Produces("application/json")
    public Response getTPBSearchResult(@DefaultValue("") @PathParam("st") String searchTerm,
            @DefaultValue("0") @PathParam("page") int page, @DefaultValue("0") @PathParam("cat") String cats) {
        PluginManager pm = OPlugin.getPluginManager();
        TrTPB trTPB = pm.getPlugin(TrTPB.class);
        if (trTPB == null) {
            return Response.status(500).entity("Plugin not found!").build();
        }
        try {
            // Build the String array of "chat" commands...
            String[] arrTerm = new String[5];
            arrTerm[0] = "DD";
            arrTerm[1] = "TPB";
            arrTerm[2] = "ST=\"" + searchTerm + "\"";
            arrTerm[3] = "PG=" + page;
            arrTerm[4] = "CAT=" + cats;
            String response = trTPB.process(arrTerm); //TPBP.query(decodedTerm, page, arrCats);
            return Response.status(200).entity(response).build();
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
    }

    /**
     * Return the description of a particular torrent object from a certain notorious torrent site.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/tpbdetails/[url-to-torrent]</p>
     *
     * @param url the url a particular torrent
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object with details of a particular torrent
     * from a notorious torrent site
     */
    @GET
    @Path("/tpbdetails/{url}")
    @Produces("application/json")
    public Response getTPBDetails(@DefaultValue("") @PathParam("url") String url) {
        PluginManager pm = OPlugin.getPluginManager();
        TrTPB trTPB = pm.getPlugin(TrTPB.class);
        if (trTPB == null) {
            return Response.status(500).entity("Plugin not found!").build();
        }
        try {
            if (url.length() > 0) {
                String[] arrTerm = new String[3];
                arrTerm[0] = "DD";
                arrTerm[1] = "TPBDETAILS";
                arrTerm[2] = url;
                String decodedURL = URLDecoder.decode(url, "UTF-8");
                if (decodedURL.startsWith("http://thepiratebay.se/")) {
                    String response = trTPB.process(arrTerm); //TPBP.queryDetails(FilenameUtils.getPath(decodedURL));
                    return Response.status(200).entity(response).build();
                }
            }
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
        return Response.status(400).entity("Unable to process TPB Details request").build();
    }

    /**
     * Return a JSON object containing the list of search results from a certain notorius torrent site.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/kas/[search-term]/[page]/[categories]</p>
     *
     * @param searchTerm the search term
     * @param page       page number to page number to serve (starts from 0)
     * @param cat       list of category number, separated by commas
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object with search results from a notorious
     * torrents site
     */
    @GET
    @Path("/kas/{st}/{page}/{cat}")
    @Produces("application/json")
    public Response getKickAssSearchResult(@DefaultValue("") @PathParam("st") String searchTerm,
            @DefaultValue("0") @PathParam("page") int page, @DefaultValue("0") @PathParam("cat") String cat) {
        PluginManager pm = OPlugin.getPluginManager();
        TrKas trKas = pm.getPlugin(TrKas.class);
        if (trKas == null) {
            return Response.status(500).entity("Plugin not found!").build();
        }
        try {
            // Build the String array of "chat" commands...
            String[] arrTerm = new String[5];
            arrTerm[0] = "DD";
            arrTerm[1] = "KAST";
            arrTerm[2] = "ST=\"" + searchTerm + "\"";
            arrTerm[3] = "PG=" + page;
            arrTerm[4] = "CAT=" + cat;
            String response = trKas.process(arrTerm);
            return Response.status(200).entity(response).build();
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
    }

    /**
     * Return the description of a particular torrent object from a certain notorious torrent site.
     * <p>URL to reach this method: http://[address-or-ip]:[port]/comm/rs/ws/kasdetails/[url-to-torrent]</p>
     *
     * @param url the url a particular torrent
     * @return a {@link javax.ws.rs.core.Response} object containing a JSON object with details of a particular torrent
     * from a notorious torrent site
     */
    @GET
    @Path("/kasdetails/{url}")
    @Produces("application/json")
    public Response getKickAssDetails(@DefaultValue("") @PathParam("url") String url) {
        PluginManager pm = OPlugin.getPluginManager();
        TrKas trKas = pm.getPlugin(TrKas.class);
        if (trKas == null) {
            return Response.status(500).entity("Plugin not found!").build();
        }
        try {
            if (url.length() > 0) {
                String[] arrTerm = new String[3];
                arrTerm[0] = "DD";
                arrTerm[1] = "KASTDETAILS";
                arrTerm[2] = url;
                String decodedURL = URLDecoder.decode(url, "UTF-8");
                if (decodedURL.startsWith("https://kickass.so/")) {
                    String response = trKas.process(arrTerm);
                    return Response.status(200).entity(response).build();
                }
            }
        } catch (Exception e) {
            return Response.status(400).entity(e.getMessage()).build();
        }
        return Response.status(400).entity("Unable to process KAST Details request").build();
    }

}