0

Init project

This commit is contained in:
2016-05-23 08:45:56 +03:00
commit 5017f5f332
12 changed files with 559 additions and 0 deletions

22
.gitignore vendored Normal file
View File

@@ -0,0 +1,22 @@
## IDEA ##
.idea/
out/
*.iml
*.ipr
*.iws
*.ids
## ECLIPSE ##
.settings/
bin/
.classpath
.project
## GRADLE ##
.gradle/
build/
## OTHER ##
lib/
target/
config.ini

65
pom.xml Normal file
View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Astral check report</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.8</java-version>
<slf4j-version>1.7.21</slf4j-version>
<log4j-version>2.5</log4j-version>
</properties>
<groupId>ru.dmitriymx</groupId>
<artifactId>astralcheckreport</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
</dependencies>
<build>
<finalName>${artifactId}-${version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,68 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-19
*/
package ru.dmitriymx.astralcheckreport;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import ru.dmitriymx.tools.browser.Browser;
import ru.dmitriymx.tools.browser.SimpleBrowser;
public class AstralSession {
private Browser browser = new SimpleBrowser();
private Gson gson = new Gson();
public AstralSession(String login, String password) {
String postData =
"ScriptManager1=UpdatePanel1%7CbtnLogin&" +
"__EVENTTARGET=&" +
"__EVENTARGUMENT=&" +
"__VIEWSTATE=%2FwEPDwUJNzM1ODg0MDkxZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAQUPY2hlY2tSZW1lbWJlck1l9d9NT50uRqRp6BAIWN1qc0s9ySLBcPB%2BoxluO6cIJmA%3D&" +
"__EVENTVALIDATION=%2FwEdAAUilyZ6nKD9WwDOh8%2FNm7H8UxXZYJerTx8fFBZzRY0g5fGnUaknU6WWWdGPJ%2BD6CIXml3mJOTUsfp8Yps0tyqTvop4oRunf14dz2Zt2%2BQKDEDuvSfxPjsGW5RjhNO7o5Y2gKe5%2Fsvh5V%2BOOTpUxCP2F&" +
"tbxLogin=" + login + "&tbxPassword=" + password + "&" +
"__ASYNCPOST=true&" +
"btnLogin=%D0%92%D1%85%D0%BE%D0%B4";
browser.post("http://reg.astralnalog.ru/Authorisation.aspx", postData);
}
public JsonObject findOrg(String inn, String kpp) {
String postData = "{\"context\":{\"CurrentPageIndex\":1,\"RecordsPerPage\":30," +
"\"AbonentName\":\"\",\"CompanyGroupName\":\"\"," +
"\"Inn\":\"" + inn + "\",\"Kpp\":\"" + kpp + "\"," +
"\"CreationDate\":\"\",\"ProductGuid\":\"\",\"RegNumPfr\":\"\",\"StepId\":\"0\"," +
"\"CreationInterval\":-1,\"SortingColumn\":\"abonentId\",\"SortingOrder\":\"desc\"}}";
browser.setHeader("Content-Type", "application/json;charset=utf-8");
String jsonStr = browser.post("http://reg.astralnalog.ru/AbonentModule.aspx/GetAbonentData", postData);
JsonObject jsonObj = str2jsonObj(jsonStr);
jsonObj = str2jsonObj(jsonObj.get("d").getAsString());
int id = jsonObj.get("rows").getAsJsonArray().get(0).getAsJsonObject().get("id").getAsInt();
postData = "{\"abonentId\":\""+ id +"\"}";
jsonStr = browser.post("http://reg.astralnalog.ru/AbonentModule.aspx/GetClientAbonentById", postData);
jsonObj = str2jsonObj(jsonStr);
jsonObj = str2jsonObj(jsonObj.get("d").getAsString());
return jsonObj;
}
public JsonObject historyCert(int productId) {
String postData = "{\"productId\":" + productId + "}";
String jsonStr = browser.post("http://reg.astralnalog.ru/AbonentModule.aspx/GetCertificatesHistory", postData);
JsonObject jsonObj = str2jsonObj(jsonStr);
return str2jsonObj(jsonObj.get("d").getAsString());
}
private JsonObject str2jsonObj(String jsonStr) {
return gson.fromJson(jsonStr, JsonObject.class);
}
@Override
public String toString() {
return super.toString();
}
}

View File

@@ -0,0 +1,27 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-20
*/
package ru.dmitriymx.astralcheckreport;
public class ExcelDataRow {
public String inn, kpp, tarif;
public int addonCert;
public int row;
public ExcelDataRow(String inn, String kpp, String tarif, int addonCert, int row) {
this.inn = inn;
this.kpp = kpp;
this.tarif = tarif;
this.addonCert = addonCert;
this.row = row;
}
@Override
public String toString() {
return "{inn: \"" + inn +
"\", kpp:\"" + kpp +
"\", tarif:\"" + tarif +
"\", addonCert:\"" + addonCert + "\"}";
}
}

View File

@@ -0,0 +1,42 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-20
*/
package ru.dmitriymx.astralcheckreport;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.IOException;
public class ExcelReader {
private Workbook xls;
private Sheet sheet;
private int startRow = 10,
currentRow = startRow;
public ExcelReader(File file, String sheetName) throws IOException, InvalidFormatException {
xls = WorkbookFactory.create(file);
sheet = xls.getSheet(sheetName);
}
public ExcelDataRow getNextData() {
Row row = sheet.getRow(currentRow++);
Cell cellInn = row.getCell(2);
cellInn.setCellType(Cell.CELL_TYPE_STRING);
if (cellInn.getStringCellValue().isEmpty()) return null;
Cell cellKpp = row.getCell(3);
cellKpp.setCellType(Cell.CELL_TYPE_STRING);
Cell cellTarif = row.getCell(6);
Cell cellAddonCert = row.getCell(11);
cellAddonCert.setCellType(Cell.CELL_TYPE_NUMERIC);
return new ExcelDataRow(
cellInn.getStringCellValue(),
cellKpp.getStringCellValue(),
cellTarif.getStringCellValue(),
(int)cellAddonCert.getNumericCellValue(),
currentRow);
}
}

View File

@@ -0,0 +1,134 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-19
*/
package ru.dmitriymx.astralcheckreport;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.dmitriymx.astralcheckreport.objects.Product;
import ru.dmitriymx.astralcheckreport.objects.Tarif;
import ru.dmitriymx.astralcheckreport.objects.TarifDeserialize;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
public class Main implements Runnable {
private Logger logger = LoggerFactory.getLogger(Main.class);
private ExcelReader excel;
private Properties properties = new Properties();
private Gson gson;
public static void main(String[] args) {
new Main().start();
}
public Main() {
gson = new GsonBuilder()
.registerTypeAdapter(Tarif.class, new TarifDeserialize())
.create();
}
public void start() {
logger.info("Astral check report v1.0");
logger.trace("Init config");
try {
properties.load(new InputStreamReader(Main.class.getResourceAsStream("/config.ini")));
} catch (IOException e) {
logger.error("Load config", e);
return;
}
logger.trace("Load excel file");
try {
excel = new ExcelReader(new File(properties.getProperty("file")),
properties.getProperty("sheet"));
} catch (IOException | InvalidFormatException e) {
logger.error("Load excel file", e);
return;
}
ThreadGroup threadGroup = new ThreadGroup("Astral Clients");
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(threadGroup, this, "ProcTH-"+(i+1));
thread.start();
safeSleep(200);
}
while (threadGroup.activeCount() > 0) {
safeSleep(100);
}
}
public synchronized ExcelDataRow nextData() {
return excel.getNextData();
}
public static void safeSleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException ignore) {
// ignore
}
}
@Override
public void run() {
logger.trace("Auth as \"{}\"...", properties.getProperty("login"));
AstralSession astral = new AstralSession(
properties.getProperty("login"),
properties.getProperty("password"));
ExcelDataRow data;
while( !Thread.currentThread().isInterrupted() && ((data = nextData()) != null) ) {
if (!data.tarif.equalsIgnoreCase("Акция 3 месяца")) continue; //FIXME
logger.info("Check {} / {} ...", data.inn, data.kpp);
logger.debug("data = {}", data);
JsonObject jsonObj = astral.findOrg(data.inn, data.kpp);
logger.debug("result = {}", jsonObj.toString());
if (data.tarif.equalsIgnoreCase("Акция 3 месяца")) {
Product product = gson.fromJson(jsonObj.get("products").getAsJsonArray().get(0), Product.class);
Tarif tarif = product.contractTariffs.get(0);
if (tarif.name.equalsIgnoreCase("Промо (3 месяца бесплатно)")) {
// 2016-03-25
int mountInit = Integer.parseInt(tarif.initialDate.substring(5, 7));
int mountEnd = Integer.parseInt(tarif.endDate.substring(5, 7));
int delta = mountEnd - mountInit;
if (delta != 3) {
logger.warn("({}/{}): tarif date error!", data.inn, data.kpp);
continue;
}
JsonObject historyCert = astral.historyCert(product.id);
int totalCert = historyCert.get("total").getAsInt();
if (totalCert > 1) {
if (totalCert != (1 + data.addonCert)) {
logger.warn("({}/{}): error history cert", data.inn, data.kpp);
continue;
}
}
} else if (tarif.name.equalsIgnoreCase("андартный (годовое обслуживание)")) {
logger.info("No logic tarif: \"{}\"", tarif.name);
} else {
logger.trace("Ignore tarif: \"{}\"", tarif.name);
}
}
safeSleep(200);
}
}
}

View File

@@ -0,0 +1,13 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-21
*/
package ru.dmitriymx.astralcheckreport.objects;
import java.util.List;
public class Product {
public int id;
public String name;
public List<Tarif> contractTariffs;
}

View File

@@ -0,0 +1,9 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-21
*/
package ru.dmitriymx.astralcheckreport.objects;
public class Tarif {
public String name, initialDate, endDate;
}

View File

@@ -0,0 +1,23 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-05-21
*/
package ru.dmitriymx.astralcheckreport.objects;
import com.google.gson.*;
import java.lang.reflect.Type;
public class TarifDeserialize implements JsonDeserializer<Tarif> {
@Override
public Tarif deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
Tarif tarif = new Tarif();
JsonObject jsonObject = jsonElement.getAsJsonObject();
tarif.name = jsonObject.get("tariff").getAsJsonObject().get("name").getAsString();
tarif.initialDate = jsonObject.get("initialDate").getAsString();
tarif.endDate = jsonObject.get("endDate").getAsString();
return tarif;
}
}

View File

@@ -0,0 +1,12 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-04-12
*/
package ru.dmitriymx.tools.browser;
public interface Browser {
void setEncoding(String encoding);
Browser setHeader(String name, String value);
String get(String url);
String post(String url, String data);
}

View File

@@ -0,0 +1,131 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-04-12
*/
package ru.dmitriymx.tools.browser;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
public class SimpleBrowser implements Browser {
private Map<String, String> headers = new HashMap<>();
private String encoding = "UTF-8";
private Map<String, String> cookieStore = new HashMap<>();
private String cookieStoreCache = null;
@Override
public void setEncoding(String encoding) {
if (encoding != null) this.encoding = encoding;
}
@Override
public Browser setHeader(String name, String value) {
headers.put(name, value);
return this;
}
@Override
public String get(String url) {
String result = "";
try {
HttpURLConnection connection = create_connection(url);
connection.setRequestMethod("GET");
if (connection.getResponseCode() != 200) return "";
saveCookie(connection.getHeaderFields());
result = readOutput(connection.getInputStream());
connection.disconnect();
} catch (IOException ignore) { //TODO прикрутить логгер
// ignore
}
return result;
}
@Override
public String post(String url, String data) {
String result = "";
try {
HttpURLConnection connection = create_connection(url);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Length", String.valueOf(data.length()));
connection.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
dos.writeBytes(data);
dos.flush();
dos.close();
if (connection.getResponseCode() != 200) return "";
saveCookie(connection.getHeaderFields());
result = readOutput(connection.getInputStream());
connection.disconnect();
} catch (IOException ignore) { //TODO прикрутить логгер
// ignore
}
return result;
}
private HttpURLConnection create_connection(String strUrl) throws IOException {
URL url = new URL(strUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false); //TODO а надо ли?
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Accept-Encoding", "deflate");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36");
connection.setRequestProperty("Cookie", loadCookie());
for (Map.Entry<String, String> entry : headers.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
return connection;
}
private String readOutput(InputStream in) throws IOException {
StringJoiner stringJoiner = new StringJoiner("\n");
BufferedReader br = new BufferedReader(new InputStreamReader(in, encoding));
String line;
while ((line = br.readLine()) != null) {
stringJoiner.add(line);
}
br.close();
return stringJoiner.toString();
}
private void saveCookie(Map<String, List<String>> headers) {
if (headers.containsKey("Set-Cookie")) {
cookieStoreCache = null;
for (String cookieLine : headers.get("Set-Cookie")) {
String cookiePair = cookieLine.split(";", 2)[0];
String[] keyValue = cookiePair.split("=");
cookieStore.put(keyValue[0], keyValue[1]);
}
}
}
private String loadCookie() {
if (cookieStoreCache == null) {
if (cookieStore.isEmpty()) {
cookieStoreCache = "";
}
StringJoiner sj = new StringJoiner(";");
for (String key : cookieStore.keySet()) {
sj.add(key + "=" + cookieStore.get(key));
}
cookieStoreCache = sj.toString();
}
return cookieStoreCache;
}
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%level] {%t} %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>