neembuu.release1.externalImpl.linkhandler.DailymotionLinkHandlerProvider.java Source code

Java tutorial

Introduction

Here is the source code for neembuu.release1.externalImpl.linkhandler.DailymotionLinkHandlerProvider.java

Source

/*
 * Copyright (C) 2014 davidepastore
 *
 * 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 neembuu.release1.externalImpl.linkhandler;

import java.util.logging.Level;
import java.util.logging.Logger;
import neembuu.release1.api.file.OnlineFile;
import neembuu.release1.api.file.PropertyProvider;
import neembuu.release1.api.linkhandler.LinkHandler;
import neembuu.release1.api.linkhandler.LinkHandlerProvider;
import neembuu.release1.api.linkhandler.TrialLinkHandler;
import neembuu.release1.api.log.LoggerUtil;
import neembuu.release1.defaultImpl.external.ELHProvider;
import neembuu.release1.defaultImpl.file.BasicOnlineFile;
import neembuu.release1.defaultImpl.file.BasicPropertyProvider;
import neembuu.release1.defaultImpl.linkhandler.BasicLinkHandler;
import neembuu.release1.defaultImpl.linkhandler.Utils;
import neembuu.release1.httpclient.NHttpClient;
import neembuu.release1.httpclient.utils.NHttpClientUtils;
import org.apache.http.client.CookieStore;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * I'm using the method explained <a href="https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/dailymotion.py">here</a>.
 * @author davidepastore
 */
@ELHProvider(checkingRegex = DailymotionLinkHandlerProvider.REG_EXP, isBroken = true)
public class DailymotionLinkHandlerProvider implements LinkHandlerProvider {

    private static final Logger LOGGER = LoggerUtil.getLogger(DailymotionLinkHandlerProvider.class.getName());
    private final DefaultHttpClient httpClient = NHttpClient.getNewInstance();
    private HttpContext httpContext;

    static final String REG_EXP = "https?://(www\\.)?dailymotion\\.com/(embed/)?video/([a-z0-9\\-_]+)|swf(/video)?/[a-zA-Z0-9]+";

    private String title;

    //Video constants
    private static final String STREAM_H264_URL = "stream_h264_url";
    private static final String STREAM_H264_LD_URL = "stream_h264_ld_url";
    private static final String STREAM_H264_HQ_URL = "stream_h264_hq_url";
    private static final String STREAM_H264_HD_URL = "stream_h264_hd_url";
    private static final String STREAM_H264_HD1080_URL = "stream_h264_hd1080_url";

    @Override
    public TrialLinkHandler tryHandling(final String url) {
        return new DM_TLH(url);
    }

    @Override
    public LinkHandler getLinkHandler(TrialLinkHandler tlh) throws Exception {
        if (!(tlh instanceof DM_TLH) || !tlh.canHandle()) {
            return null;
        }
        BasicLinkHandler.Builder linkHandlerBuilder = extraction(tlh);
        return linkHandlerBuilder.build();
    }

    /**
     * Set the cookies to allow to watch more videos and to force to use english.
     */
    private void setCookies() {
        httpContext = new BasicHttpContext();
        CookieStore cookieStore = new BasicCookieStore();

        //Add the cookies value
        cookieStore.addCookie(new BasicClientCookie("family_filter", "off"));
        cookieStore.addCookie(new BasicClientCookie("ff", "off"));
        cookieStore.addCookie(new BasicClientCookie("lang", "en_US"));

        httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

    }

    /**
     * Find JSON.
     * @param dailyMotionUrl The DailyMotion url.
     */
    private String findJson(String dailyMotionUrl) {
        String response = "";
        try {
            final String id = dailyMotionUrl.replaceAll(REG_EXP, "$3");

            //System.out.println("The id of the video is: " + id);

            response = NHttpClientUtils.getData("http://www.dailymotion.com/embed/video/" + id, httpClient);
            String regExp = "(?m)var info = \\{(.*?)\\},$";

            if (true)
                throw new UnsupportedOperationException("Please do not use appwork stuff here."
                        + " Having dependency on libraries which are highly unstable will make us cry in future.");
            //probably make a regex utility here in neembuu
            //and we shall share that utility in NU and NN
            //response = new org.appwork.utils.Regex(response, regExp).getMatch(0);

            response = "{" + response + "}";

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return response;
    }

    /**
     * Extract the urls.
     * @param url the vimeo url.
     * @return An ArrayList<String> with all the urls found for this video.
     */
    private BasicLinkHandler.Builder extraction(TrialLinkHandler tlh) throws Exception {
        return extraction(tlh, 0);
    }

    private BasicLinkHandler.Builder extraction(TrialLinkHandler tlh, int retryCount) throws Exception {
        BasicLinkHandler.Builder linkHandlerBuilder = BasicLinkHandler.Builder.create();
        setCookies();
        try {
            String jSonString = findJson(tlh.getReferenceLinkString());

            JSONObject jSonObject = new JSONObject(jSonString);
            //System.out.println("JSON Object: " + jSonObject);

            title = jSonObject.getString("title");
            long duration = jSonObject.getLong("duration") * 1000;
            long cDuration = duration;

            //Set the group name as the name of the video
            linkHandlerBuilder.setGroupName(title);

            //Add all the videos for the link handler builder
            if (!jSonObject.isNull(STREAM_H264_LD_URL)) {
                createFileBuilder(jSonObject.getString(STREAM_H264_LD_URL), title, "LD", duration,
                        linkHandlerBuilder);
            }

            if (!jSonObject.isNull(STREAM_H264_URL)) {
                createFileBuilder(jSonObject.getString(STREAM_H264_URL), title, "SD", duration, linkHandlerBuilder);
            }

            if (!jSonObject.isNull(STREAM_H264_HQ_URL)) {
                createFileBuilder(jSonObject.getString(STREAM_H264_HQ_URL), title, "HQ", duration,
                        linkHandlerBuilder);
            }

            if (!jSonObject.isNull(STREAM_H264_HD_URL)) {
                createFileBuilder(jSonObject.getString(STREAM_H264_HD_URL), title, "HD", duration,
                        linkHandlerBuilder);
            }

            if (!jSonObject.isNull(STREAM_H264_HD1080_URL)) {
                createFileBuilder(jSonObject.getString(STREAM_H264_HD1080_URL), title, "HD", duration,
                        linkHandlerBuilder);
            }

            for (OnlineFile of : linkHandlerBuilder.getFiles()) {
                long dur = of.getPropertyProvider()
                        .getLongPropertyValue(PropertyProvider.LongProperty.MEDIA_DURATION_IN_MILLISECONDS);
                if (dur < 0 && cDuration > 0 && of.getPropertyProvider() instanceof BasicPropertyProvider) {
                    ((BasicPropertyProvider) of.getPropertyProvider()).putLongPropertyValue(
                            PropertyProvider.LongProperty.MEDIA_DURATION_IN_MILLISECONDS, cDuration);
                }
            }

        } catch (JSONException ex) {
            int retryLimit = ((DM_TLH) tlh).retryLimit;
            ex.printStackTrace();
            System.out.println("retry no. = " + retryCount);
            if (retryCount > retryLimit)
                throw ex;
            return extraction(tlh, retryCount + 1);
        }

        return linkHandlerBuilder;
    }

    private void createFileBuilder(String url, String title, String quality, long duration,
            BasicLinkHandler.Builder linkHandlerBuilder) {
        long length;
        try {
            length = NHttpClientUtils.calculateLength(url, httpClient);
        } catch (Exception e) {
            return;
        }

        BasicOnlineFile.Builder fileBuilder = linkHandlerBuilder.createFile();

        fileBuilder.setName(title + " " + quality + ".mp4")
                .putLongPropertyValue(PropertyProvider.LongProperty.MEDIA_DURATION_IN_MILLISECONDS, duration)
                .putStringPropertyValue(PropertyProvider.StringProperty.VARIANT_DESCRIPTION, quality).setUrl(url)
                .setSize(length).next();
    }

    static final class DM_TLH implements TrialLinkHandler {

        private final String url;
        private int retryLimit = 5;

        public void setRetryLimit(int retryLimit) {
            this.retryLimit = retryLimit;
        }

        DM_TLH(String url) {
            this.url = Utils.normalize(url);
        }

        /**
         * 
         * @param url
         * @return 
         */
        @Override
        public boolean canHandle() {
            boolean result = url.matches(REG_EXP);
            LOGGER.log(Level.INFO, "DailyMotion can handle this? {0}", result);
            return result;
        }

        @Override
        public String getErrorMessage() {
            return canHandle() ? null : "Cannot handle";
        }

        @Override
        public boolean containsMultipleLinks() {
            return true;
        }

        @Override
        public String tempDisplayName() {
            return url;
        }

        @Override
        public String getReferenceLinkString() {
            return url;
        }
    };

}