work on 8ch posting

multisite
Floens 8 years ago
parent 10ed72775e
commit 5ad19883f3
  1. 58
      Clover/app/src/main/java/org/floens/chan/core/site/common/CommonReplyHttpCall.java
  2. 11
      Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCall.java
  3. 7
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java
  4. 72
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4ReplyCall.java
  5. 36
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
  6. 70
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ReplyHttpCall.java

@ -15,14 +15,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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("<!-- thread:([0-9]+),no:([0-9]+) -->");
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);
}

@ -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) {

@ -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<Chan4ReplyHttpCall>() {
httpCallManager.makeHttpCall(new Chan4ReplyCall(this, reply), new HttpCall.HttpCallback<CommonReplyHttpCall>() {
@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);
}
});

@ -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 <http://www.gnu.org/licenses/>.
*/
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");
}
}
}

@ -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,8 +194,13 @@ public class Chan8 extends SiteBase {
@Override
public boolean feature(Feature feature) {
switch (feature) {
case POSTING:
return true;
default:
return false;
}
}
@Override
public boolean boardFeature(BoardFeature boardFeature, Board board) {
@ -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<CommonReplyHttpCall>() {
@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

@ -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 <http://www.gnu.org/licenses/>.
*/
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");
}
}
}
Loading…
Cancel
Save