diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyHttpCall.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/CommonReplyHttpCall.java
similarity index 63%
rename from Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyHttpCall.java
rename to Clover/app/src/main/java/org/floens/chan/core/site/common/CommonReplyHttpCall.java
index b2595830..7747145f 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyHttpCall.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/CommonReplyHttpCall.java
@@ -15,14 +15,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.floens.chan.core.site.sites.chan4;
-
-import android.text.TextUtils;
+package org.floens.chan.core.site.common;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.http.HttpCall;
-import org.floens.chan.core.site.http.ReplyResponse;
import org.floens.chan.core.site.http.Reply;
+import org.floens.chan.core.site.http.ReplyResponse;
import org.jsoup.Jsoup;
import java.io.IOException;
@@ -30,14 +28,13 @@ import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import okhttp3.MediaType;
+import okhttp3.HttpUrl;
import okhttp3.MultipartBody;
import okhttp3.Request;
-import okhttp3.RequestBody;
import okhttp3.Response;
-public class Chan4ReplyHttpCall extends HttpCall {
- private static final String TAG = "Chan4ReplyHttpCall";
+public abstract class CommonReplyHttpCall extends HttpCall {
+ private static final String TAG = "CommonReplyHttpCall";
private static final Random RANDOM = new Random();
private static final Pattern THREAD_NO_PATTERN = Pattern.compile("");
private static final Pattern ERROR_MESSAGE = Pattern.compile("\"errmsg\"[^>]*>(.*?)<\\/span");
@@ -46,56 +43,23 @@ public class Chan4ReplyHttpCall extends HttpCall {
public final Reply reply;
public final ReplyResponse replyResponse = new ReplyResponse();
- public Chan4ReplyHttpCall(Site site, Reply reply) {
+ public CommonReplyHttpCall(Site site, Reply reply) {
super(site);
this.reply = reply;
}
@Override
public void setup(Request.Builder requestBuilder) {
- boolean thread = reply.loadable.isThreadMode();
-
replyResponse.password = Long.toHexString(RANDOM.nextLong());
MultipartBody.Builder formBuilder = new MultipartBody.Builder();
formBuilder.setType(MultipartBody.FORM);
- formBuilder.addFormDataPart("mode", "regist");
- formBuilder.addFormDataPart("pwd", replyResponse.password);
-
- if (thread) {
- formBuilder.addFormDataPart("resto", String.valueOf(reply.loadable.no));
- }
-
- formBuilder.addFormDataPart("name", reply.name);
- formBuilder.addFormDataPart("email", reply.options);
-
- if (!thread && !TextUtils.isEmpty(reply.subject)) {
- formBuilder.addFormDataPart("sub", reply.subject);
- }
-
- formBuilder.addFormDataPart("com", reply.comment);
+ addParameters(formBuilder);
- if (reply.captchaResponse != null) {
- if (reply.captchaChallenge != null) {
- formBuilder.addFormDataPart("recaptcha_challenge_field", reply.captchaChallenge);
- formBuilder.addFormDataPart("recaptcha_response_field", reply.captchaResponse);
- } else {
- formBuilder.addFormDataPart("g-recaptcha-response", reply.captchaResponse);
- }
- }
-
- if (reply.file != null) {
- formBuilder.addFormDataPart("upfile", reply.fileName, RequestBody.create(
- MediaType.parse("application/octet-stream"), reply.file
- ));
- }
-
- if (reply.spoilerImage) {
- formBuilder.addFormDataPart("spoiler", "on");
- }
-
- requestBuilder.url(site.endpoints().reply(reply.loadable));
+ HttpUrl replyUrl = site.endpoints().reply(this.reply.loadable);
+ requestBuilder.url(replyUrl);
+ requestBuilder.addHeader("Referer", replyUrl.toString());
requestBuilder.post(formBuilder.build());
}
@@ -120,4 +84,6 @@ public class Chan4ReplyHttpCall extends HttpCall {
}
}
}
+
+ public abstract void addParameters(MultipartBody.Builder builder);
}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCall.java b/Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCall.java
index 310eff26..2fceb22b 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCall.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCall.java
@@ -28,6 +28,7 @@ import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.Response;
+import okhttp3.ResponseBody;
/**
* Http calls are an abstraction over a normal OkHttp call.
@@ -55,19 +56,21 @@ public abstract class HttpCall implements Callback {
@Override
public void onResponse(Call call, Response response) {
+ ResponseBody body = response.body();
try {
- if (response.isSuccessful() && response.body() != null) {
- String responseString = response.body().string();
+ if (response.isSuccessful() && body != null) {
+ String responseString = body.string();
process(response, responseString);
successful = true;
} else {
- onFailure(call, null);
+ String responseString = body == null ? "no body" : body.string();
+ onFailure(call, new IOException("HTTP " + response.code() + "\n\n" + responseString));
}
} catch (Exception e) {
exception = e;
Logger.e(TAG, "IOException processing response", e);
} finally {
- IOUtils.closeQuietly(response.body());
+ IOUtils.closeQuietly(body);
}
if (successful) {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java
index b0ebfb8c..01742158 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java
@@ -40,6 +40,7 @@ import org.floens.chan.core.site.SiteEndpoints;
import org.floens.chan.core.site.SiteIcon;
import org.floens.chan.core.site.SiteRequestModifier;
import org.floens.chan.core.site.common.ChanReader;
+import org.floens.chan.core.site.common.CommonReplyHttpCall;
import org.floens.chan.core.site.common.FutabaChanReader;
import org.floens.chan.core.site.http.DeleteRequest;
import org.floens.chan.core.site.http.HttpCall;
@@ -408,14 +409,14 @@ public class Chan4 extends SiteBase {
@Override
public void post(Reply reply, final PostListener postListener) {
- httpCallManager.makeHttpCall(new Chan4ReplyHttpCall(this, reply), new HttpCall.HttpCallback() {
+ httpCallManager.makeHttpCall(new Chan4ReplyCall(this, reply), new HttpCall.HttpCallback() {
@Override
- public void onHttpSuccess(Chan4ReplyHttpCall httpPost) {
+ public void onHttpSuccess(CommonReplyHttpCall httpPost) {
postListener.onPostComplete(httpPost, httpPost.replyResponse);
}
@Override
- public void onHttpFail(Chan4ReplyHttpCall httpPost, Exception e) {
+ public void onHttpFail(CommonReplyHttpCall httpPost, Exception e) {
postListener.onPostError(httpPost);
}
});
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyCall.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyCall.java
new file mode 100644
index 00000000..c5819266
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyCall.java
@@ -0,0 +1,72 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * 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 .
+ */
+package org.floens.chan.core.site.sites.chan4;
+
+import android.text.TextUtils;
+
+import org.floens.chan.core.site.Site;
+import org.floens.chan.core.site.common.CommonReplyHttpCall;
+import org.floens.chan.core.site.http.Reply;
+
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.RequestBody;
+
+public class Chan4ReplyCall extends CommonReplyHttpCall {
+ public Chan4ReplyCall(Site site, Reply reply) {
+ super(site, reply);
+ }
+
+ @Override
+ public void addParameters(MultipartBody.Builder formBuilder) {
+ formBuilder.addFormDataPart("mode", "regist");
+ formBuilder.addFormDataPart("pwd", replyResponse.password);
+
+ if (reply.loadable.isThreadMode()) {
+ formBuilder.addFormDataPart("resto", String.valueOf(reply.loadable.no));
+ }
+
+ formBuilder.addFormDataPart("name", reply.name);
+ formBuilder.addFormDataPart("email", reply.options);
+
+ if (!reply.loadable.isThreadMode() && !TextUtils.isEmpty(reply.subject)) {
+ formBuilder.addFormDataPart("sub", reply.subject);
+ }
+
+ formBuilder.addFormDataPart("com", reply.comment);
+
+ if (reply.captchaResponse != null) {
+ if (reply.captchaChallenge != null) {
+ formBuilder.addFormDataPart("recaptcha_challenge_field", reply.captchaChallenge);
+ formBuilder.addFormDataPart("recaptcha_response_field", reply.captchaResponse);
+ } else {
+ formBuilder.addFormDataPart("g-recaptcha-response", reply.captchaResponse);
+ }
+ }
+
+ if (reply.file != null) {
+ formBuilder.addFormDataPart("upfile", reply.fileName, RequestBody.create(
+ MediaType.parse("application/octet-stream"), reply.file
+ ));
+ }
+
+ if (reply.spoilerImage) {
+ formBuilder.addFormDataPart("spoiler", "on");
+ }
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
index 72b2f102..5f176799 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
@@ -33,12 +33,15 @@ import org.floens.chan.core.site.SiteEndpoints;
import org.floens.chan.core.site.SiteIcon;
import org.floens.chan.core.site.SiteRequestModifier;
import org.floens.chan.core.site.common.ChanReader;
+import org.floens.chan.core.site.common.CommonReplyHttpCall;
import org.floens.chan.core.site.common.FutabaChanParser;
import org.floens.chan.core.site.common.FutabaChanReader;
import org.floens.chan.core.site.http.DeleteRequest;
import org.floens.chan.core.site.http.HttpCall;
+import org.floens.chan.core.site.http.HttpCallManager;
import org.floens.chan.core.site.http.LoginRequest;
import org.floens.chan.core.site.http.Reply;
+import org.floens.chan.utils.Logger;
import java.util.Locale;
import java.util.Map;
@@ -49,6 +52,8 @@ import okhttp3.Request;
import static org.floens.chan.Chan.getGraph;
public class Chan8 extends SiteBase {
+ private static final String TAG = "Chan8";
+
public static final Resolvable RESOLVABLE = new Resolvable() {
@Override
public ResolveResult resolve(String value) {
@@ -78,6 +83,11 @@ public class Chan8 extends SiteBase {
.host("media.8ch.net")
.build();
+ private final HttpUrl sys = new HttpUrl.Builder()
+ .scheme("https")
+ .host("sys.8ch.net")
+ .build();
+
@Override
public HttpUrl catalog(Board board) {
return root.newBuilder()
@@ -133,7 +143,9 @@ public class Chan8 extends SiteBase {
@Override
public HttpUrl reply(Loadable loadable) {
- return null;
+ return sys.newBuilder()
+ .addPathSegment("post.php")
+ .build();
}
@Override
@@ -182,7 +194,12 @@ public class Chan8 extends SiteBase {
@Override
public boolean feature(Feature feature) {
- return false;
+ switch (feature) {
+ case POSTING:
+ return true;
+ default:
+ return false;
+ }
}
@Override
@@ -231,7 +248,22 @@ public class Chan8 extends SiteBase {
}
@Override
- public void post(Reply reply, PostListener postListener) {
+ public void post(Reply reply, final PostListener postListener) {
+ // TODO
+ HttpCallManager httpCallManager = getGraph().get(HttpCallManager.class);
+ httpCallManager.makeHttpCall(new Chan8ReplyHttpCall(this, reply), new HttpCall.HttpCallback() {
+ @Override
+ public void onHttpSuccess(CommonReplyHttpCall httpPost) {
+ postListener.onPostComplete(httpPost, httpPost.replyResponse);
+ }
+
+ @Override
+ public void onHttpFail(CommonReplyHttpCall httpPost, Exception e) {
+ Logger.e(TAG, "post error", e);
+
+ postListener.onPostError(httpPost);
+ }
+ });
}
@Override
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ReplyHttpCall.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ReplyHttpCall.java
new file mode 100644
index 00000000..092da71c
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ReplyHttpCall.java
@@ -0,0 +1,70 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * 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 .
+ */
+package org.floens.chan.core.site.sites.chan8;
+
+import android.text.TextUtils;
+
+import org.floens.chan.core.site.Site;
+import org.floens.chan.core.site.http.Reply;
+import org.floens.chan.core.site.common.CommonReplyHttpCall;
+
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.RequestBody;
+
+public class Chan8ReplyHttpCall extends CommonReplyHttpCall {
+ public Chan8ReplyHttpCall(Site site, Reply reply) {
+ super(site, reply);
+ }
+
+ @Override
+ public void addParameters(MultipartBody.Builder formBuilder) {
+// formBuilder.addFormDataPart("pwd", replyResponse.password);
+
+ formBuilder.addFormDataPart("board", reply.loadable.board.code);
+
+ if (reply.loadable.isThreadMode()) {
+ formBuilder.addFormDataPart("post", "New Reply");
+
+ formBuilder.addFormDataPart("thread", String.valueOf(reply.loadable.no));
+ } else {
+ formBuilder.addFormDataPart("post", "New Thread");
+
+ formBuilder.addFormDataPart("page", "1");
+ }
+
+ formBuilder.addFormDataPart("name", reply.name);
+ formBuilder.addFormDataPart("email", reply.options);
+
+ if (!reply.loadable.isThreadMode() && !TextUtils.isEmpty(reply.subject)) {
+ formBuilder.addFormDataPart("subject", reply.subject);
+ }
+
+ formBuilder.addFormDataPart("body", reply.comment);
+
+ if (reply.file != null) {
+ formBuilder.addFormDataPart("file", reply.fileName, RequestBody.create(
+ MediaType.parse("application/octet-stream"), reply.file
+ ));
+ }
+
+ if (reply.spoilerImage) {
+ formBuilder.addFormDataPart("spoiler", "on");
+ }
+ }
+}