-
Notifications
You must be signed in to change notification settings - Fork 61
/
SubmitLoader.java
156 lines (122 loc) · 4.45 KB
/
SubmitLoader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package com.airlocksoftware.hackernews.loader;
import java.io.IOException;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import com.airlocksoftware.hackernews.activity.SubmitActivity.SendMode;
import com.airlocksoftware.hackernews.data.ConnectionManager;
import com.airlocksoftware.hackernews.data.UserPrefs;
import com.airlocksoftware.hackernews.model.NewStoryResult;
public class SubmitLoader extends AsyncTaskLoader<NewStoryResult> {
final String mSelfText, mUrl, mTitle;
final SendMode mSendMode;
// Constants
private static final String TAG = SubmitLoader.class.getSimpleName();
private static final String REPLY_EXTENSION = "/r";
// Don't care about HTTP vs HTTPS
private static final String MATCH_NEWEST_PAGE = "://news.ycombinator.com/newest";
// Match substrings for error messages
private static final String MATCH_POST_TOO_FAST = "submitting too fast";
// Match duplicate posts
private static final String MATCH_DUPLICATE_PAGE = "item?id=";
private enum ErrorMessage {
POST_SUCCESS, POST_TOO_FAST, POST_DUPLICATE
}
public ErrorMessage mErrorMessage = ErrorMessage.POST_SUCCESS;
public SubmitLoader(Context context, SendMode sendMode, String title, String content) {
super(context);
mSendMode = sendMode;
switch (mSendMode) {
case URL:
mSelfText = "";
mTitle = title;
mUrl = content;
break;
case SELF_TEXT:
mSelfText = content;
mTitle = title;
mUrl = "";
break;
default:
mSelfText = mUrl = mTitle = null;
break;
}
}
@Override
public NewStoryResult loadInBackground() {
if (mSendMode == SendMode.EMPTY) return NewStoryResult.EMPTY;
UserPrefs data = new UserPrefs(getContext());
try {
String replyFnid = getReplyFnid(data);
Connection.Response response = sendSubmission(data, replyFnid);
validateResponse(response);
switch (mErrorMessage) {
case POST_SUCCESS:
return NewStoryResult.SUCCESS;
case POST_DUPLICATE:
return NewStoryResult.POST_DUPLICATE;
case POST_TOO_FAST:
return NewStoryResult.POST_TOO_FAST;
default:
return NewStoryResult.FAILURE;
}
} catch (Exception e) {
// any exception here probably means we have NO_CONNECTION or there's an error with the website.
e.printStackTrace();
}
return NewStoryResult.FAILURE;
}
private boolean validateResponse(Connection.Response res) {
if (res == null) return false;
if (res.headers() != null && res.headers().get("Location") != null) {
Crashlytics.setString("SubmitLoader :: responseLocationHeader", res.headers().get("Location"));
}
if (res.url() != null) {
Crashlytics.setString("SubmitLoader :: responseURL", res.url().toString());
}
// This used to work
if (res.statusCode() == 302 && res.headers().get("Location").equals("newest")) {
mErrorMessage = ErrorMessage.POST_SUCCESS;
// This currently works
} else if (res.statusCode() == 200 && res.url().toString().contains(MATCH_NEWEST_PAGE)) {
mErrorMessage = ErrorMessage.POST_SUCCESS;
// If you post too fast, HN complains
} else if (res.body().contains(MATCH_POST_TOO_FAST)) {
Crashlytics.setBool("SubmitLoader :: responsePostTooFast", true);
mErrorMessage = ErrorMessage.POST_TOO_FAST;
// If the URL contains 'item?id=', it's a duplicate post
} else if (res.url() != null && res.url().toString().contains(MATCH_DUPLICATE_PAGE)) {
Crashlytics.setBool("SubmitLoader :: responsePostDuplicate", true);
mErrorMessage = ErrorMessage.POST_DUPLICATE;
}
// Only POST_SUCCESS is 100% clean and successful
return mErrorMessage == ErrorMessage.POST_SUCCESS;
}
private Response sendSubmission(UserPrefs data, String replyFnid) throws IOException {
return ConnectionManager.authConnect(REPLY_EXTENSION, data.getUserCookie())
.data("fnid", replyFnid)
.data("t", mTitle)
.data("u", mUrl)
.data("x", mSelfText)
.method(Method.POST)
.execute();
}
private String getReplyFnid(UserPrefs data) throws IOException {
return ConnectionManager.authConnect(ConnectionManager.SUBMIT_URL, data.getUserCookie())
.get()
.select("input[name=fnid]")
.first()
.attr("value");
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
forceLoad();
}
}