From 2b21c914f95a43ce4c0e18538fb1cf5ba703e1f0 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 10 Apr 2017 14:09:09 +0300 Subject: [PATCH] Init project --- .gitignore | 24 +++ pom.xml | 58 +++++++ src/main/java/ru/dmitriymx/vkapi/Browser.java | 12 ++ .../java/ru/dmitriymx/vkapi/Response.java | 11 ++ src/main/java/ru/dmitriymx/vkapi/VkApi.java | 149 ++++++++++++++++++ .../ru/dmitriymx/vkapi/VkApiException.java | 17 ++ 6 files changed, 271 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/ru/dmitriymx/vkapi/Browser.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/Response.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/VkApi.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/VkApiException.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a44b3d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +## IDEA ## +.idea/ +out/ +*.iml +*.ipr +*.iws +*.ids + +## ECLIPSE ## +.settings/ +bin/ +.classpath +.project + +## GRADLE ## +.gradle/ +build/ + +## MAVEN ## +target/ + +## OTHER ## +lib/ + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..cdb8bba --- /dev/null +++ b/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + VK Api Uni + + ru.dmitriymx + vkapiuni + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.7.21 + + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + + com.google.code.gson + gson + 2.8.0 + + + + + ${project.artifactId}-${project.version} + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=${project.build.sourceEncoding} + + + + + diff --git a/src/main/java/ru/dmitriymx/vkapi/Browser.java b/src/main/java/ru/dmitriymx/vkapi/Browser.java new file mode 100644 index 0000000..e7d3693 --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/Browser.java @@ -0,0 +1,12 @@ +/* + * DmitriyMX + * 2017-04-10 + */ +package ru.dmitriymx.vkapi; + +import java.io.IOException; + +public interface Browser { + Response get(String url) throws IOException; + Response post(String url, String data) throws IOException; +} diff --git a/src/main/java/ru/dmitriymx/vkapi/Response.java b/src/main/java/ru/dmitriymx/vkapi/Response.java new file mode 100644 index 0000000..12cc623 --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/Response.java @@ -0,0 +1,11 @@ +/* + * DmitriyMX + * 2017-04-10 + */ +package ru.dmitriymx.vkapi; + +public interface Response { + int getStatus(); + String getContentType(); + String getContent(); +} diff --git a/src/main/java/ru/dmitriymx/vkapi/VkApi.java b/src/main/java/ru/dmitriymx/vkapi/VkApi.java new file mode 100644 index 0000000..b301ed0 --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/VkApi.java @@ -0,0 +1,149 @@ +/* + * DmitriyMX + * 2017-04-10 + */ +package ru.dmitriymx.vkapi; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Map; +import java.util.stream.Collectors; + +public class VkApi { + private static final String VKAPI_URL = "https://api.vk.com/method/"; + private final Logger logger = LoggerFactory.getLogger(VkApi.class); + private final String accessToken; + private final Browser browser; + private final Gson gson; + private String apiVersion = "5.62"; + private long callPause = 1200L; + private long lastTime; + private int call = 0; + + public VkApi(String accessToken, Browser browser) { + if (accessToken == null || accessToken.trim().isEmpty()) { + throw new RuntimeException("Access token don't be NULL or EMPTY!"); + } + this.accessToken = accessToken; + this.browser = browser; + this.gson = new Gson(); + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public long getCallPause() { + return callPause; + } + + public void setCallPause(long callPause) { + this.callPause = callPause; + } + + public JsonObject execApi(String methodApi, Map params) throws VkApiException { + checkCalls(); + String url = VKAPI_URL + methodApi; + String postData = paramsToString(params); + + Response response; + try { + response = browser.post(url, postData); + } catch (IOException e) { + throw new RuntimeException(e); + } + + chechResponse(response); + + JsonObject jsonObject = gson.fromJson(response.getContent(), JsonObject.class); + if (jsonObject.has("error")) { + throw new VkApiException(jsonObject); + } + + return jsonObject; + } + + public JsonObject longExecApi(String server, String key, long ts, long wait) throws VkApiException { + String url = String.format("https://%s?act=a_check&key=%s&ts=%d&wait=%d&mode=2&version=1", + server, key, ts, wait + ); + + Response response; + try { + response = browser.get(url); + } catch (IOException e) { + throw new RuntimeException(e); + } + + chechResponse(response); + + JsonObject jsonObject = gson.fromJson(response.getContent(), JsonObject.class); + if (jsonObject.has("error")) { + throw new VkApiException(jsonObject); + } + + return jsonObject; + } + + private String paramsToString(Map params) { + String collect = ""; + if (params != null && params.size() > 0) { + collect = "&" + params.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("&")); + } + return "access_token=" + accessToken + "&v=" + apiVersion + collect; + } + + private void checkCalls() { + if (call >= 3) { + long currTime = System.currentTimeMillis(); + long diff = currTime - lastTime; + + if (diff <= callPause) { + safeSleep(callPause); + } + + lastTime = System.currentTimeMillis(); + call = 0; + } else { + safeSleep(callPause/3); + call++; + } + } + + private void chechResponse(Response response) { + if (response.getStatus() != 200) { + throw new IllegalStateException(String.format("code != 200 (%d)", response.getStatus())); + } + + if (!response.getContentType().equalsIgnoreCase("application/json") && + !response.getContentType().equalsIgnoreCase("text/javascript")) { + throw new IllegalStateException(String.format("content type is not JSON/JavaScript (%s)", response.getContentType())); + } + + if (response.getContent().isEmpty()) { + throw new IllegalStateException("content is empty"); + } + + if (logger.isDebugEnabled()) { + logger.debug(response.getContent()); + } + } + + private void safeSleep(long ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException ignore) { + // ignore + } + } +} diff --git a/src/main/java/ru/dmitriymx/vkapi/VkApiException.java b/src/main/java/ru/dmitriymx/vkapi/VkApiException.java new file mode 100644 index 0000000..baf2f86 --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/VkApiException.java @@ -0,0 +1,17 @@ +/* + * DmitriyMX + * 2017-04-10 + */ +package ru.dmitriymx.vkapi; + +import com.google.gson.JsonObject; + +public class VkApiException extends Exception { + public VkApiException(String message) { + super(message); + } + + public VkApiException(JsonObject jsonObject) { + this(jsonObject.getAsJsonObject("error").get("error_msg").getAsString()); + } +}