/*
* Copyright (C) 2015 Shashank Tulsyan <shashaank at neembuu.com>
*
* 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.uploader.captcha;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import neembuu.uploader.uploaders.common.StringUtils;
import neembuu.uploader.utils.NUHttpClientUtils;
import neembuu.uploader.utils.NULogger;
import org.apache.http.protocol.HttpContext;
/**
* This class allows you to search within a string, the k challenge, the c challenge,
* the captcha image and displays it to the user to obtain in this way the input.
* @author davidepastore
*/
public class CaptchaImpl implements Captcha{
private String string;
private String formTitle;
/* Google */
private String googleRegK = "http://www\\.google\\.com/recaptcha/api/challenge\\?k=";
private String googleRegC = "challenge.*?:.*?'(.*?)',";
private String googleURL = "http://www.google.com/recaptcha/api/image?c=";
/* Recaptcha */
private String recaptchaRegK = "http://www\\.api\\.recaptcha\\.net/challenge\\?k=";
private Pattern regex;
private Matcher regexMatcher;
private int start;
private int end;
private String kCaptchaUrl;
private String cCaptchaUrl;
private HttpContext httpContext;
private URL imageURL;
private final CaptchaForm captchaForm;
/**
* Every how many milliseconds to check if the form of captcha has been closed.
*/
private final static long WAIT_TIME = 1000;
/**
* Basic constructor without setting string. If you already have the K challenge link,
* you can use this and then set the formTitle with <b>setFormTitle()</b>.
*/
public CaptchaImpl(){
this(null);
}
/**
* Constructor
* @param string The string into which you want to find the captcha urls.
*/
public CaptchaImpl(String string){
this(string,null);
}
/**
* Constructor
* @param string The string into which you want to find the captcha urls.
* @param formTitle The form title.
*/
public CaptchaImpl(String string, String formTitle){
this.string = string;
this.formTitle = formTitle;
captchaForm = new CaptchaForm();
}
/**
* Find the K Challenge URL.
* @return The K Challenge URL as a String.
* @throws Exception
*/
@Override
public String findKCaptchaUrl() throws Exception{
kCaptchaUrl = null;
//FileUtils.saveInFile("Recaptcha.html", string);
//For google
regex = Pattern.compile(googleRegK);
regexMatcher = regex.matcher(string);
if(regexMatcher.find()){
//NULogger.getLogger().info("Google K recaptcha found!");
start = regexMatcher.start();
string = string.substring(start);
end = string.indexOf("\"");
kCaptchaUrl = string.substring(0, end);
NULogger.getLogger().log(Level.INFO, "kCaptchaUrl: {0}", kCaptchaUrl);
return kCaptchaUrl;
}
//For recaptcha
regex = Pattern.compile(recaptchaRegK);
regexMatcher = regex.matcher(string);
if(regexMatcher.find()){
//NULogger.getLogger().info("Recaptcha K recaptcha found!");
start = regexMatcher.start();
string = string.substring(start);
end = string.indexOf("\"");
kCaptchaUrl = string.substring(0, end);
NULogger.getLogger().log(Level.INFO, "kCaptchaUrl: {0}", kCaptchaUrl);
return kCaptchaUrl;
}
return null;
}
/**
* Find the C Challenge URL.
* @return The C Challenge URL as a String.
* @throws Exception
*/
@Override
public String findCCaptchaUrl() throws Exception{
return findCCaptchaUrlFromK(kCaptchaUrl);
}
/**
* Find the C Challenge URL from the given K Challenge URL.
* @param kCaptchaUrl The K Challenge URL as a String.
* @return The C Challenge URL as a String..
* @throws IOException
*/
@Override
public String findCCaptchaUrlFromK(String kCaptchaUrl) throws IOException, Exception{
cCaptchaUrl = null;
if(kCaptchaUrl == null){
return null;
}
String body = NUHttpClientUtils.getData(kCaptchaUrl, httpContext);
//CommonUploaderTasks.saveInFile("Recaptcha.html", body);
regex = Pattern.compile(googleRegC);
regexMatcher = regex.matcher(body);
if(regexMatcher.find()){
NULogger.getLogger().info("Google C recaptcha found!");
cCaptchaUrl = body.substring(regexMatcher.start(), regexMatcher.end());
cCaptchaUrl = StringUtils.stringBetweenTwoStrings(cCaptchaUrl, "'", "'");
NULogger.getLogger().log(Level.INFO, "cCaptchaUrl: {0}", cCaptchaUrl);
return cCaptchaUrl;
}
NULogger.getLogger().log(Level.INFO, "kCaptchaUrl: {0}", kCaptchaUrl);
return cCaptchaUrl;
}
/**
* Find the captcha image URL.
* @return The captcha image URL as an URL.
* @throws IOException
* @throws Exception
*/
@Override
public URL findCaptchaImageURL() throws IOException, Exception{
imageURL = new URL(googleURL+cCaptchaUrl);
return imageURL;
}
/**
* Return the captcha string (entered by user).
* @return The captcha string (entered by user).
* @throws InterruptedException
*/
@Override
public String getCaptchaString() throws InterruptedException {
//CaptchaForm captchaForm;
//captchaForm = new CaptchaForm(imageURL, formTitle, httpContext);
captchaForm.setImageURL(imageURL);
captchaForm.setTitle(formTitle);
captchaForm.setHttpContext(httpContext);
captchaForm.setVisible(true);
NULogger.getLogger().info("Captcha Form opened.");
//Is this the better method?
while(!captchaForm.isClosing){
Thread.sleep(WAIT_TIME);
}
NULogger.getLogger().log(Level.INFO, "Captcha Form closed. I read: {0}", captchaForm.captchaString);
return captchaForm.captchaString;
}
/**
* Get C Captcha Url.
* @return The C Captcha Url.
*/
@Override
public String getCCaptchaUrl(){
return cCaptchaUrl;
}
/**
* Set the title of the form.
* @param title The title of the form.
*/
@Override
public void setFormTitle(String title){
this.formTitle = title;
}
/**
* Set the image URL.
* @param imageUrl The image URL (URL type).
*/
@Override
public void setImageURL(URL imageUrl){
this.imageURL = imageUrl;
}
/**
* Set the image URL.
* @param imageUrl The image URL (String type).
*/
@Override
public void setImageURL(String imageUrl) throws MalformedURLException{
this.setImageURL(new URL(imageUrl));
}
/**
* Set the HttpContext
* @param httpContext
*/
@Override
public void setHttpContext(HttpContext httpContext) {
this.httpContext = httpContext;
}
@Override
public void destroy() {
captchaForm.destory();
}
}