package com.alkor.vph;
import com.alkor.vph.captcha.CaptchaParser;
import com.alkor.vph.tasks.VKBotTask;
import com.alkor.vph.vk.VKTokenProvider;
import com.alkor.vph.vk.entities.Captcha;
import com.alkor.vph.vk.entities.MethodResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.util.List;
/**
* Author: akorobitsyn
* Date: 08.07.13
* Time: 15:35
*/
public class VKBot implements Runnable {
private final Log log = LogFactory.getLog(VKBot.class);
private final VKTokenProvider vkTokenProvider;
private final CaptchaParser captchaParser;
private final String wallPostFile;
private final long sleepTime;
private final List<VKBotTask> tasks;
private int currentTask = 0;
public static VKBot createInstance(List<VKBotTask> tasks, VKTokenProvider vkTokenProvider, String wallPostFile, CaptchaParser captchaParser) {
return new VKBot(tasks, vkTokenProvider, captchaParser, wallPostFile, 5000);
}
public static VKBot createInstance(List<VKBotTask> tasks, VKTokenProvider vkTokenProvider, CaptchaParser captchaParser, String wallPostFile, long sleepTime) {
return new VKBot(tasks, vkTokenProvider, captchaParser, wallPostFile, sleepTime);
}
@Override
public void run() {
Captcha captcha = null;
while (currentTask < tasks.size()) {
try {
VKBotTask VKBotTask = tasks.get(currentTask);
currentTask++;
if (checkGroup(VKBotTask.getTaskId())) {
continue;
}
if (VKBotTask.shouldBeSkipped()) {
continue;
}
MethodResult wallPostResult = VKBotTask.post(captcha, vkTokenProvider.getToken());
captcha = null;
log.info(VKBotTask);
log.info(wallPostResult);
if (wallPostResult.isSuccess()) {
writeGroup(VKBotTask.getTaskId());
} else {
if (wallPostResult.getErrorCode() == 5 || wallPostResult.getErrorCode() == 1) {
if (!changeToken()) {
break;
}
continue;
}
if (wallPostResult.getErrorCode() == 14) {
captcha = wallPostResult.getCaptcha();
captcha.setCaptchaKey(captchaParser.parseCaptcha(captcha.getCaptchaImg()));
log.info(String.format("Captcha requested: %s", captcha));
currentTask--;
continue;
}
if (wallPostResult.getErrorCode() == 214) {
if ("Access to adding post denied: access to the wall is closed".equals(wallPostResult.getMessage())) {
writeGroup(VKBotTask.getTaskId());
} else if ("Access to adding post denied: too many messages sent".equals(wallPostResult.getMessage())) {
if (!changeToken()) {
break;
};
}
}
}
Thread.sleep(sleepTime);
} catch (Exception e) {
log.error("Task stopped by exception", e);
break;
}
}
}
private VKBot(List<VKBotTask> tasks, VKTokenProvider vkTokenProvider, CaptchaParser captchaParser, String wallPostFile, long sleepTime) {
this.vkTokenProvider = vkTokenProvider;
this.captchaParser = captchaParser;
this.tasks = tasks;
this.wallPostFile = wallPostFile;
this.sleepTime = sleepTime;
log.info(String.format("Start token is %s", vkTokenProvider.getToken()));
}
private boolean changeToken() {
boolean success = vkTokenProvider.switchToken();
if (success) {
currentTask--;
log.info(String.format("Token has been changed to %s", vkTokenProvider.getToken()));
} else {
log.info(String.format("Token has not been changed"));
}
return success;
}
private void writeGroup(String gid) throws IOException {
BufferedWriter output = new BufferedWriter(new FileWriter(wallPostFile, true));
try {
output.append(String.valueOf(gid));
output.newLine();
} finally {
output.close();
}
}
private boolean checkGroup(String gid) throws IOException {
File file = new File(wallPostFile);
if (!file.exists()) {
return false;
}
FileInputStream fileInputStream = new FileInputStream(file);
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
if (line.equals(String.valueOf(gid))) {
return true;
}
}
} finally {
fileInputStream.close();
}
return false;
}
}