aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/ru
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/ru')
-rw-r--r--src/main/java/ru/sape/Sape.java23
-rw-r--r--src/main/java/ru/sape/SapeConnection.java108
-rw-r--r--src/main/java/ru/sape/SapePageLinks.java76
3 files changed, 207 insertions, 0 deletions
diff --git a/src/main/java/ru/sape/Sape.java b/src/main/java/ru/sape/Sape.java
new file mode 100644
index 00000000..38577c45
--- /dev/null
+++ b/src/main/java/ru/sape/Sape.java
@@ -0,0 +1,23 @@
+/*
+ * http://code.google.com/p/javasape/
+ */
+package ru.sape;
+
+public class Sape {
+
+ private final String sapeUser;
+ private final SapeConnection sapePageLinkConnection;
+
+ public Sape(String sapeUser, String host, int socketTimeout, int cacheLifeTime) {
+ this.sapeUser = sapeUser;
+
+ this.sapePageLinkConnection = new SapeConnection(
+ "/code.php?user=" + sapeUser + "&host=" + host,
+ "SAPE_Client PHP", socketTimeout, cacheLifeTime);
+ }
+ public boolean debug = false;
+
+ public SapePageLinks getPageLinks(String requestUri, String cookie) {
+ return new SapePageLinks(sapePageLinkConnection, sapeUser, requestUri, cookie, debug);
+ }
+}
diff --git a/src/main/java/ru/sape/SapeConnection.java b/src/main/java/ru/sape/SapeConnection.java
new file mode 100644
index 00000000..a15658fa
--- /dev/null
+++ b/src/main/java/ru/sape/SapeConnection.java
@@ -0,0 +1,108 @@
+package ru.sape;
+
+import com.github.ooxi.phparser.SerializedPhpParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+
+public class SapeConnection {
+ private static final Logger logger = LoggerFactory.getLogger(SapeConnection.class);
+ private final String version = "1.0.3";
+ private final List<String> serverList = Arrays.asList("dispenser-01.sape.ru", "dispenser-02.sape.ru");
+ private final String dispenserPath;
+ private final String userAgent;
+ private final int socketTimeout;
+ private final int cacheLifeTime;
+
+ public SapeConnection(String dispenserPath, String userAgent, int socketTimeout, int cacheLifeTime) {
+ this.dispenserPath = dispenserPath;
+ this.userAgent = userAgent;
+ this.socketTimeout = socketTimeout;
+ this.cacheLifeTime = cacheLifeTime;
+ }
+
+ protected String fetchRemoteFile(String host, String path) throws IOException {
+ Reader r = null;
+
+ try {
+ HttpURLConnection connection = (HttpURLConnection) ((new URL(("http://" + host + path)).openConnection()));
+
+ if (socketTimeout > 0) {
+ connection.setConnectTimeout(socketTimeout);
+ connection.setReadTimeout(socketTimeout);
+ }
+
+ connection.addRequestProperty("User-Agent", userAgent + ' ' + version);
+
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setUseCaches(false);
+ connection.setRequestMethod("GET");
+ connection.connect();
+
+ r = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+
+ StringWriter sw = new StringWriter();
+
+ int b;
+
+ while ((b = r.read()) != -1) {
+ sw.write(b);
+ }
+
+ return sw.toString();
+ } finally {
+ if (r != null) {
+ r.close();
+ }
+ }
+ }
+ Map<String, Object> cached;
+ long cacheUpdated;
+
+ @SuppressWarnings("unchecked")
+ public Map<String, Object> getData() {
+ if (cacheLifeTime <= (System.currentTimeMillis() - cacheUpdated) / 1000) {
+ for (String server : serverList) {
+ String data;
+
+ try {
+ data = fetchRemoteFile(server, dispenserPath + "&charset=UTF-8");
+ } catch (IOException e1) {
+ continue;
+ }
+
+ if (data.startsWith("FATAL ERROR:")) {
+ logger.error("Sape responded with error: {}", data);
+
+ continue;
+ }
+
+ try {
+ cached = (Map<String, Object>) new SerializedPhpParser(data).parse();
+ } catch (Exception e) {
+ logger.error("Can't parse Sape data", e);
+ continue;
+ }
+
+ cacheUpdated = System.currentTimeMillis();
+
+ return cached;
+ }
+
+ logger.error("Unable to fetch Sape data");
+
+ return Collections.emptyMap();
+ }
+
+ return cached;
+ }
+}
diff --git a/src/main/java/ru/sape/SapePageLinks.java b/src/main/java/ru/sape/SapePageLinks.java
new file mode 100644
index 00000000..e89b4e71
--- /dev/null
+++ b/src/main/java/ru/sape/SapePageLinks.java
@@ -0,0 +1,76 @@
+package ru.sape;
+
+import java.util.*;
+
+public class SapePageLinks {
+
+ private boolean showCode;
+
+ public SapePageLinks(SapeConnection sapeConnection, String sapeUser, String requestUri, String sapeCookie) {
+ this(sapeConnection, sapeUser, requestUri, sapeCookie, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public SapePageLinks(SapeConnection sapeConnection, String sapeUser, String requestUri, String sapeCookie, boolean showCode) {
+ if (sapeUser.equals(sapeCookie)) {
+ showCode = true;
+ }
+
+ Map<String, Object> data = sapeConnection.getData();
+
+ if (data.containsKey("__sape_delimiter__")) {
+ linkDelimiter = (String) data.get("__sape_delimiter__");
+ }
+
+ if (data.containsKey(requestUri)) {
+ pageLinks = new ArrayList<>(((Map<Object, String>) data.get(requestUri)).values());
+ }
+
+ if (data.containsKey("__sape_new_url__")) {
+ if (showCode) {
+ Object newUrl = data.get("__sape_new_url__");
+
+ if (newUrl instanceof Map) {
+ pageLinks = new ArrayList<>(((Map<Object, String>) newUrl).values());
+ } else {
+ pageLinks = new ArrayList<>(Collections.singletonList((String) newUrl));
+ }
+ }
+ }
+
+ this.showCode = showCode;
+ }
+ private String linkDelimiter = ".";
+ private List<String> pageLinks = new ArrayList<>();
+
+ public String render() {
+ return render(-1);
+ }
+
+ public String render(int count) {
+ StringBuilder s = new StringBuilder();
+
+ if (count < 0) {
+ count = pageLinks.size();
+ }
+
+ for (Iterator<String> i = pageLinks.iterator(); i.hasNext() && count > 0; count--) {
+ if (s.length() > 0) {
+ s.append(linkDelimiter);
+ }
+
+ String l = i.next();
+
+ s.append(l);
+
+ i.remove();
+ }
+
+ if (showCode) {
+ s.insert(0, "<sape_noindex>");
+ s.append("</sape_noindex>");
+ }
+
+ return s.toString();
+ }
+}