tweaking dns
This commit is contained in:
parent
6ca8f3b384
commit
0d87425259
|
@ -0,0 +1,8 @@
|
|||
package org.mariotaku.twidere.test;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/11.
|
||||
*/
|
||||
public class OkHttpTest {
|
||||
|
||||
}
|
|
@ -44,7 +44,7 @@ public class DebugModeUtils {
|
|||
|
||||
private static RefWatcher sRefWatcher;
|
||||
|
||||
public static void initForHttpClient(final OkHttpClient.Builder builder) {
|
||||
public static void initForOkHttpClient(final OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new StethoInterceptor());
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ public class HotMobiLogger implements HotMobiConstants {
|
|||
return prefs.getLong(KEY_LAST_UPLOAD_TIME, -1);
|
||||
}
|
||||
|
||||
public static boolean log(final String msg) {
|
||||
public static boolean printLog(final String msg) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
final StackTraceElement ste = new Throwable().fillInStackTrace().getStackTrace()[1];
|
||||
final String fullName = ste.getClassName();
|
||||
|
|
|
@ -23,23 +23,21 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.util.BugReporter;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import edu.tsinghua.hotmobi.model.UploadLogEvent;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Upload logs to target server
|
||||
|
@ -48,24 +46,22 @@ import okhttp3.Response;
|
|||
public class UploadLogsTask implements Runnable {
|
||||
|
||||
private final Context context;
|
||||
private final OkHttpClient client;
|
||||
|
||||
public UploadLogsTask(Context context) {
|
||||
this.context = context;
|
||||
this.client = new OkHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final SharedPreferences prefs = context.getSharedPreferences("spice_data_profiling", Context.MODE_PRIVATE);
|
||||
final SharedPreferences prefs = context.getSharedPreferences(HotMobiConstants.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
|
||||
if (prefs.contains(HotMobiConstants.KEY_LAST_UPLOAD_TIME)) {
|
||||
final long lastUpload = prefs.getLong(HotMobiConstants.KEY_LAST_UPLOAD_TIME, System.currentTimeMillis());
|
||||
final double deltaDays = (System.currentTimeMillis() - lastUpload) /
|
||||
(double) HotMobiLogger.UPLOAD_INTERVAL_MILLIS;
|
||||
if (deltaDays < 1) {
|
||||
HotMobiLogger.log("Last uploaded was conducted in 1 day ago.");
|
||||
HotMobiLogger.printLog("Last uploaded was conducted in 1 day ago.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -86,25 +82,32 @@ public class UploadLogsTask implements Runnable {
|
|||
return !filename.equalsIgnoreCase(todayDir);
|
||||
}
|
||||
};
|
||||
for (Object dayLogsDirObj : ArrayUtils.nullToEmpty(logsDir.listFiles(filter))) {
|
||||
final File dayLogsDir = (File) dayLogsDirObj;
|
||||
File[] dayLogsDirs = logsDir.listFiles(filter);
|
||||
if (dayLogsDirs == null) return false;
|
||||
for (File dayLogsDir : dayLogsDirs) {
|
||||
File[] logFiles = dayLogsDir.listFiles();
|
||||
if (logFiles == null) continue;
|
||||
boolean succeeded = true;
|
||||
for (Object logFileObj : ArrayUtils.nullToEmpty(dayLogsDir.listFiles())) {
|
||||
File logFile = (File) logFileObj;
|
||||
for (File logFile : logFiles) {
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
final Request.Builder builder = new Request.Builder();
|
||||
builder.url("http://www.dnext.xyz/usage/upload");
|
||||
builder.header("X-HotMobi-UUID", uuid);
|
||||
builder.header("X-HotMobi-Date", dayLogsDir.getName());
|
||||
builder.header("X-HotMobi-FileName", logFile.getName());
|
||||
builder.header("User-Agent", String.format(Locale.ROOT,
|
||||
final UploadLogEvent uploadLogEvent = UploadLogEvent.create(context, logFile);
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL("http://www.dnext.xyz/usage/upload").openConnection();
|
||||
conn.setRequestProperty("X-HotMobi-UUID", uuid);
|
||||
conn.setRequestProperty("X-HotMobi-Date", dayLogsDir.getName());
|
||||
conn.setRequestProperty("X-HotMobi-FileName", logFile.getName());
|
||||
conn.setRequestProperty("User-Agent", String.format(Locale.ROOT,
|
||||
"HotMobi (Twidere %s %d)", BuildConfig.VERSION_NAME,
|
||||
BuildConfig.VERSION_CODE));
|
||||
builder.method("POST", RequestBody.create(MediaType.parse("text/plain"), logFile));
|
||||
final UploadLogEvent uploadLogEvent = UploadLogEvent.create(context, logFile);
|
||||
final Response response = client.newCall(builder.build()).execute();
|
||||
if (response.isSuccessful()) {
|
||||
uploadLogEvent.finish(response);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
os = conn.getOutputStream();
|
||||
is = new FileInputStream(logFile);
|
||||
Utils.copyStream(is, os);
|
||||
final int responseCode = conn.getResponseCode();
|
||||
if (responseCode >= 200 && responseCode < 300) {
|
||||
uploadLogEvent.finish(conn);
|
||||
if (!uploadLogEvent.shouldSkip()) {
|
||||
HotMobiLogger.getInstance(context).log(uploadLogEvent);
|
||||
}
|
||||
|
@ -114,6 +117,9 @@ public class UploadLogsTask implements Runnable {
|
|||
Log.w(HotMobiLogger.LOGTAG, e);
|
||||
succeeded = false;
|
||||
hasErrors = true;
|
||||
} finally {
|
||||
Utils.closeSilently(is);
|
||||
Utils.closeSilently(os);
|
||||
}
|
||||
}
|
||||
if (succeeded) {
|
||||
|
|
|
@ -12,21 +12,19 @@ import com.hannesdorfmann.parcelableplease.annotation.Bagger;
|
|||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/2.
|
||||
*/
|
||||
@ParcelablePlease
|
||||
@JsonObject
|
||||
public class UploadLogEvent extends BaseEvent implements Parcelable {
|
||||
private static final String X_DNEXT_PREFIX = "X-Dnext";
|
||||
public static final Creator<UploadLogEvent> CREATOR = new Creator<UploadLogEvent>() {
|
||||
public UploadLogEvent createFromParcel(Parcel source) {
|
||||
UploadLogEvent target = new UploadLogEvent();
|
||||
|
@ -83,19 +81,23 @@ public class UploadLogEvent extends BaseEvent implements Parcelable {
|
|||
UploadLogEventParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public void finish(Response response) {
|
||||
public void finish(HttpURLConnection response) {
|
||||
HashMap<String, String> extraHeaders = new HashMap<>();
|
||||
final Headers headers = response.headers();
|
||||
for (int i = 0, j = headers.size(); i < j; i++) {
|
||||
final String name = headers.name(i);
|
||||
if (StringUtils.startsWithIgnoreCase(name, "X-Dnext")) {
|
||||
extraHeaders.put(name, headers.value(i));
|
||||
final Map<String, List<String>> headers = response.getHeaderFields();
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
final String name = entry.getKey();
|
||||
if (name == null) continue;
|
||||
if (name.regionMatches(true, 0, X_DNEXT_PREFIX, 0, X_DNEXT_PREFIX.length())) {
|
||||
for (String value : entry.getValue()) {
|
||||
extraHeaders.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
setExtraHeaders(extraHeaders);
|
||||
markEnd();
|
||||
}
|
||||
|
||||
|
||||
public static UploadLogEvent create(Context context, File file) {
|
||||
UploadLogEvent event = new UploadLogEvent();
|
||||
event.markStart(context);
|
||||
|
|
|
@ -161,6 +161,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
|
|||
mDrawerLayout.closeDrawers();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public long[] getActivatedAccountIds() {
|
||||
final Fragment fragment = getLeftDrawerFragment();
|
||||
if (fragment instanceof AccountsDashboardFragment) {
|
||||
|
|
|
@ -139,8 +139,6 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
|||
migrateUsageStatisticsPreferences();
|
||||
Utils.startRefreshServiceIfNeeded(this);
|
||||
|
||||
reloadConnectivitySettings();
|
||||
|
||||
DependencyHolder holder = DependencyHolder.get(this);
|
||||
registerActivityLifecycleCallbacks(holder.getActivityTracker());
|
||||
|
||||
|
@ -263,9 +261,12 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
|||
final RestHttpClient client = holder.getRestHttpClient();
|
||||
if (client instanceof OkHttpRestClient) {
|
||||
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
HttpClientFactory.initDefaultHttpClient(this, holder.getPreferences(), builder,
|
||||
HttpClientFactory.initOkHttpClient(this, holder.getPreferences(), builder,
|
||||
holder.getDns());
|
||||
((OkHttpRestClient) client).setClient(builder.build());
|
||||
final OkHttpRestClient restClient = (OkHttpRestClient) client;
|
||||
// Kill all connections
|
||||
restClient.getClient().connectionPool().evictAll();
|
||||
restClient.setClient(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,18 @@ package org.mariotaku.twidere.fragment;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -71,8 +76,21 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
return inflater.inflate(R.layout.fragment_network_diagnostics, container, false);
|
||||
}
|
||||
|
||||
private void appendMessage(String message) {
|
||||
mLogTextView.append(message);
|
||||
private void appendMessage(LogText message) {
|
||||
SpannableString coloredText = SpannableString.valueOf(message.message);
|
||||
switch (message.state) {
|
||||
case LogText.State.GOOD: {
|
||||
coloredText.setSpan(new ForegroundColorSpan(Color.GREEN), 0, coloredText.length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
break;
|
||||
}
|
||||
case LogText.State.BAD: {
|
||||
coloredText.setSpan(new ForegroundColorSpan(Color.RED), 0, coloredText.length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mLogTextView.append(coloredText);
|
||||
}
|
||||
|
||||
static class DiagnosticsTask extends AsyncTask<Object, LogText, Object> {
|
||||
|
@ -146,7 +164,7 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
testDns(dns, host);
|
||||
testNativeLookup(host);
|
||||
} else {
|
||||
publishProgress(new LogText("API URL format is invalid"));
|
||||
publishProgress(new LogText("API URL format is invalid", LogText.State.BAD));
|
||||
publishProgress(LogText.LINEBREAK);
|
||||
}
|
||||
|
||||
|
@ -197,9 +215,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
} else {
|
||||
publishProgress(new LogText(String.valueOf(dns.lookup(host))));
|
||||
}
|
||||
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis() - start)));
|
||||
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis()
|
||||
- start), LogText.State.GOOD));
|
||||
} catch (UnknownHostException e) {
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage()));
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
|
||||
}
|
||||
publishProgress(LogText.LINEBREAK);
|
||||
}
|
||||
|
@ -209,9 +228,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
try {
|
||||
final long start = SystemClock.uptimeMillis();
|
||||
publishProgress(new LogText(Arrays.toString(InetAddress.getAllByName(host))));
|
||||
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis() - start)));
|
||||
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis()
|
||||
- start), LogText.State.GOOD));
|
||||
} catch (UnknownHostException e) {
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage()));
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
|
||||
}
|
||||
publishProgress(LogText.LINEBREAK);
|
||||
}
|
||||
|
@ -221,9 +241,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
try {
|
||||
final long start = SystemClock.uptimeMillis();
|
||||
test.execute(twitter);
|
||||
publishProgress(new LogText(String.format("OK (%d ms)", SystemClock.uptimeMillis() - start)));
|
||||
publishProgress(new LogText(String.format("OK (%d ms)", SystemClock.uptimeMillis()
|
||||
- start), LogText.State.GOOD));
|
||||
} catch (TwitterException e) {
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage()));
|
||||
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
|
||||
}
|
||||
publishProgress(LogText.LINEBREAK);
|
||||
}
|
||||
|
@ -238,7 +259,7 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
NetworkDiagnosticsFragment fragment = mFragmentRef.get();
|
||||
if (fragment == null) return;
|
||||
for (LogText value : values) {
|
||||
fragment.appendMessage(value.message);
|
||||
fragment.appendMessage(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,9 +303,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
static class LogText {
|
||||
static final LogText LINEBREAK = new LogText("\n");
|
||||
String message;
|
||||
int state;
|
||||
@State
|
||||
int state = State.DEFAULT;
|
||||
|
||||
LogText(String message, int state) {
|
||||
LogText(String message, @State int state) {
|
||||
this.message = message;
|
||||
this.state = state;
|
||||
}
|
||||
|
@ -292,6 +314,13 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
|
|||
LogText(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@IntDef({State.DEFAULT, State.GOOD, State.BAD})
|
||||
@interface State {
|
||||
int DEFAULT = 0;
|
||||
int GOOD = 1;
|
||||
int BAD = 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -153,6 +153,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo
|
|||
};
|
||||
private boolean mSwitchAccountAnimationPlaying;
|
||||
|
||||
@NonNull
|
||||
public long[] getActivatedAccountIds() {
|
||||
if (mAccountActionProvider != null) {
|
||||
return mAccountActionProvider.getActivatedAccountIds();
|
||||
|
|
|
@ -233,9 +233,11 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
|
|||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Object... params) {
|
||||
final Context context = getContext();
|
||||
if (context == null) return null;
|
||||
final long[][] result = new long[2][];
|
||||
result[0] = getAccountIds();
|
||||
result[1] = DataStoreUtils.getNewestMessageIds(getActivity(),
|
||||
result[1] = DataStoreUtils.getNewestMessageIds(context,
|
||||
DirectMessages.Inbox.CONTENT_URI, result[0]);
|
||||
return result;
|
||||
}
|
||||
|
@ -243,7 +245,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
|
|||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (twitter == null) return;
|
||||
if (twitter == null || result == null) return;
|
||||
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
|
||||
twitter.getSentDirectMessagesAsync(result[0], null, null);
|
||||
}
|
||||
|
@ -326,6 +328,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
|
|||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected long[] getAccountIds() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.getLong(EXTRA_ACCOUNT_ID) > 0) {
|
||||
|
@ -368,13 +371,13 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
|
|||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Object... params) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null) return null;
|
||||
final Context context = getContext();
|
||||
if (context == null) return null;
|
||||
final long[][] result = new long[3][];
|
||||
result[0] = getAccountIds();
|
||||
result[1] = DataStoreUtils.getOldestMessageIds(activity,
|
||||
result[1] = DataStoreUtils.getOldestMessageIds(context,
|
||||
DirectMessages.Inbox.CONTENT_URI, result[0]);
|
||||
result[2] = DataStoreUtils.getOldestMessageIds(activity,
|
||||
result[2] = DataStoreUtils.getOldestMessageIds(context,
|
||||
DirectMessages.Outbox.CONTENT_URI, result[0]);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package org.mariotaku.twidere.model;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/11.
|
||||
*/
|
||||
public class RefreshTaskParam {
|
||||
|
||||
private final long[] accountIds, maxIds, sinceIds;
|
||||
|
||||
public long[] getAccountIds() {
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
public long[] getMaxIds() {
|
||||
return maxIds;
|
||||
}
|
||||
|
||||
public long[] getSinceIds() {
|
||||
return sinceIds;
|
||||
}
|
||||
|
||||
public RefreshTaskParam(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
this.accountIds = accountIds;
|
||||
this.maxIds = maxIds;
|
||||
this.sinceIds = sinceIds;
|
||||
}
|
||||
}
|
|
@ -22,8 +22,8 @@ package org.mariotaku.twidere.task;
|
|||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.twitter.Extractor;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
|
@ -40,7 +40,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class CacheUsersStatusesTask extends AsyncTask<TwitterListResponse<Status>, Object, Object> implements Constants {
|
||||
public class CacheUsersStatusesTask extends TaskRunnable<TwitterListResponse<Status>, Object, Object> implements Constants {
|
||||
|
||||
private final Context context;
|
||||
|
||||
|
@ -48,49 +48,44 @@ public class CacheUsersStatusesTask extends AsyncTask<TwitterListResponse<Status
|
|||
this.context = context;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@Override
|
||||
protected final Object doInBackground(final TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status>... args) {
|
||||
if (args == null || args.length == 0) return null;
|
||||
public final Object doLongOperation(final TwitterListResponse<Status> params) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Extractor extractor = new Extractor();
|
||||
|
||||
for (final TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status> response : args) {
|
||||
if (response == null || !response.hasData()) {
|
||||
continue;
|
||||
}
|
||||
final List<org.mariotaku.twidere.api.twitter.model.Status> list = response.getData();
|
||||
for (int bulkIdx = 0, totalSize = list.size(); bulkIdx < totalSize; bulkIdx += 100) {
|
||||
for (int idx = bulkIdx, end = Math.min(totalSize, bulkIdx + ContentResolverUtils.MAX_BULK_COUNT); idx < end; idx++) {
|
||||
final org.mariotaku.twidere.api.twitter.model.Status status = list.get(idx);
|
||||
if (params == null || !params.hasData()) {
|
||||
return null;
|
||||
}
|
||||
final List<Status> list = params.getData();
|
||||
for (int bulkIdx = 0, totalSize = list.size(); bulkIdx < totalSize; bulkIdx += 100) {
|
||||
for (int idx = bulkIdx, end = Math.min(totalSize, bulkIdx + ContentResolverUtils.MAX_BULK_COUNT); idx < end; idx++) {
|
||||
final Status status = list.get(idx);
|
||||
|
||||
final Set<ContentValues> usersValues = new HashSet<>();
|
||||
final Set<ContentValues> statusesValues = new HashSet<>();
|
||||
final Set<ContentValues> hashTagValues = new HashSet<>();
|
||||
final Set<ContentValues> usersValues = new HashSet<>();
|
||||
final Set<ContentValues> statusesValues = new HashSet<>();
|
||||
final Set<ContentValues> hashTagValues = new HashSet<>();
|
||||
|
||||
statusesValues.add(ContentValuesCreator.createStatus(status, response.accountId));
|
||||
final String text = TwitterContentUtils.unescapeTwitterStatusText(status.getText());
|
||||
for (final String hashtag : extractor.extractHashtags(text)) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(CachedHashtags.NAME, hashtag);
|
||||
hashTagValues.add(values);
|
||||
}
|
||||
final ContentValues cachedUser = ContentValuesCreator.createCachedUser(status.getUser());
|
||||
cachedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
|
||||
usersValues.add(cachedUser);
|
||||
if (status.isRetweet()) {
|
||||
final ContentValues cachedRetweetedUser = ContentValuesCreator.createCachedUser(status.getRetweetedStatus().getUser());
|
||||
cachedRetweetedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
|
||||
usersValues.add(cachedRetweetedUser);
|
||||
}
|
||||
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedStatuses.CONTENT_URI, statusesValues);
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedHashtags.CONTENT_URI, hashTagValues);
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedUsers.CONTENT_URI, usersValues);
|
||||
statusesValues.add(ContentValuesCreator.createStatus(status, params.accountId));
|
||||
final String text = TwitterContentUtils.unescapeTwitterStatusText(status.getText());
|
||||
for (final String hashtag : extractor.extractHashtags(text)) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(CachedHashtags.NAME, hashtag);
|
||||
hashTagValues.add(values);
|
||||
}
|
||||
final ContentValues cachedUser = ContentValuesCreator.createCachedUser(status.getUser());
|
||||
cachedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
|
||||
usersValues.add(cachedUser);
|
||||
if (status.isRetweet()) {
|
||||
final ContentValues cachedRetweetedUser = ContentValuesCreator.createCachedUser(status.getRetweetedStatus().getUser());
|
||||
cachedRetweetedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
|
||||
usersValues.add(cachedRetweetedUser);
|
||||
}
|
||||
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedStatuses.CONTENT_URI, statusesValues);
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedHashtags.CONTENT_URI, hashTagValues);
|
||||
ContentResolverUtils.bulkInsert(resolver, CachedUsers.CONTENT_URI, usersValues);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.annotation.ReadPositionTag;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.api.twitter.model.Status;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
|
||||
import org.mariotaku.twidere.util.ErrorInfoStore;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/11.
|
||||
*/
|
||||
public class GetActivitiesAboutMeTask extends GetActivitiesTask {
|
||||
|
||||
public GetActivitiesAboutMeTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_INTERACTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveReadPosition(long accountId, Twitter twitter) {
|
||||
try {
|
||||
CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
|
||||
final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountId);
|
||||
readStateManager.setPosition(tag, response.getCursor(), false);
|
||||
} catch (TwitterException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, final long accountId, final Paging paging) throws TwitterException {
|
||||
if (Utils.shouldUsePrivateAPIs(context, accountId)) {
|
||||
return twitter.getActivitiesAboutMe(paging);
|
||||
}
|
||||
final ResponseList<Activity> activities = new ResponseList<>();
|
||||
for (Status status : twitter.getMentionsTimeline(paging)) {
|
||||
activities.add(Activity.fromMention(accountId, status));
|
||||
}
|
||||
return activities;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return TwidereDataStore.Activities.AboutMe.CONTENT_URI;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
|
||||
import org.mariotaku.twidere.util.ErrorInfoStore;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/11.
|
||||
*/
|
||||
public class GetActivitiesByFriendsTask extends GetActivitiesTask {
|
||||
|
||||
public GetActivitiesByFriendsTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_ACTIVITIES_BY_FRIENDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveReadPosition(long accountId, Twitter twitter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseList<Activity> getActivities(@NonNull Twitter twitter, long accountId, Paging paging) throws TwitterException {
|
||||
return twitter.getActivitiesByFriends(paging);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return TwidereDataStore.Activities.ByFriends.CONTENT_URI;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.api.twitter.model.Status;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
|
||||
import org.mariotaku.twidere.util.ErrorInfoStore;
|
||||
|
||||
import edu.tsinghua.hotmobi.model.TimelineType;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/11.
|
||||
*/
|
||||
public class GetHomeTimelineTask extends GetStatusesTask {
|
||||
|
||||
public GetHomeTimelineTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ResponseList<Status> getStatuses(final Twitter twitter, final Paging paging)
|
||||
throws TwitterException {
|
||||
return twitter.getHomeTimeline(paging);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return TwidereDataStore.Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@TimelineType
|
||||
@Override
|
||||
protected String getTimelineType() {
|
||||
return TimelineType.HOME;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,62 +5,74 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.Log;
|
||||
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.api.twitter.model.Status;
|
||||
import org.mariotaku.twidere.model.ParcelableActivity;
|
||||
import org.mariotaku.twidere.model.RefreshTaskParam;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.DataStoreUtils;
|
||||
import org.mariotaku.twidere.util.ErrorInfoStore;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
import org.mariotaku.twidere.util.message.GetActivitiesTaskEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/4.
|
||||
*/
|
||||
public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object, Object> {
|
||||
public abstract class GetActivitiesTask extends TaskRunnable<RefreshTaskParam, Object, Object> implements Constants {
|
||||
|
||||
protected final AsyncTwitterWrapper twitterWrapper;
|
||||
protected final long[] accountIds;
|
||||
protected final long[] maxIds;
|
||||
protected final long[] sinceIds;
|
||||
protected final Context context;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper preferences;
|
||||
@Inject
|
||||
protected Bus bus;
|
||||
@Inject
|
||||
protected ErrorInfoStore errorInfoStore;
|
||||
@Inject
|
||||
protected ReadStateManager readStateManager;
|
||||
|
||||
public GetActivitiesTask(AsyncTwitterWrapper twitterWrapper, String tag, long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
super(twitterWrapper.getContext(), tag);
|
||||
this.twitterWrapper = twitterWrapper;
|
||||
this.accountIds = accountIds;
|
||||
this.maxIds = maxIds;
|
||||
this.sinceIds = sinceIds;
|
||||
public GetActivitiesTask(Context context) {
|
||||
this.context = context;
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(Object... params) {
|
||||
final Context context = twitterWrapper.getContext();
|
||||
public Object doLongOperation(RefreshTaskParam param) {
|
||||
final long[] accountIds = param.getAccountIds(), maxIds = param.getMaxIds(), sinceIds = param.getSinceIds();
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
final int loadItemLimit = twitterWrapper.getPreferences().getInt(KEY_LOAD_ITEM_LIMIT);
|
||||
final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT);
|
||||
boolean saveReadPosition = false;
|
||||
for (int i = 0; i < accountIds.length; i++) {
|
||||
final long accountId = accountIds[i];
|
||||
final boolean noItemsBefore = DataStoreUtils.getActivitiesCount(context,
|
||||
getContentUri(), accountId) <= 0;
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId,
|
||||
true);
|
||||
final boolean noItemsBefore = DataStoreUtils.getActivitiesCount(context, getContentUri(),
|
||||
accountId) <= 0;
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true);
|
||||
if (twitter == null) continue;
|
||||
final Paging paging = new Paging();
|
||||
paging.count(loadItemLimit);
|
||||
if (maxIds != null && maxIds[i] > 0) {
|
||||
|
@ -73,10 +85,9 @@ public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object,
|
|||
saveReadPosition = true;
|
||||
}
|
||||
}
|
||||
final ErrorInfoStore errorInfoStore = twitterWrapper.getErrorInfoStore();
|
||||
// We should delete old activities has intersection with new items
|
||||
try {
|
||||
final ResponseList<Activity> activities = getActivities(accountId, twitter, paging);
|
||||
final ResponseList<Activity> activities = getActivities(twitter, accountId, paging);
|
||||
storeActivities(cr, loadItemLimit, accountId, noItemsBefore, activities);
|
||||
// if (saveReadPosition && TwitterAPIFactory.isOfficialTwitterInstance(context, twitter)) {
|
||||
if (saveReadPosition) {
|
||||
|
@ -141,19 +152,26 @@ public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object,
|
|||
|
||||
protected abstract void saveReadPosition(long accountId, Twitter twitter);
|
||||
|
||||
protected abstract ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException;
|
||||
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, final long accountId, final Paging paging) throws TwitterException {
|
||||
if (Utils.shouldUsePrivateAPIs(context, accountId)) {
|
||||
return twitter.getActivitiesAboutMe(paging);
|
||||
}
|
||||
final ResponseList<Activity> activities = new ResponseList<>();
|
||||
for (Status status : twitter.getMentionsTimeline(paging)) {
|
||||
activities.add(Activity.fromMention(accountId, status));
|
||||
}
|
||||
return activities;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object result) {
|
||||
super.onPostExecute(result);
|
||||
public void callback(Object result) {
|
||||
bus.post(new GetActivitiesTaskEvent(getContentUri(), false, null));
|
||||
}
|
||||
|
||||
protected abstract Uri getContentUri();
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
@UiThread
|
||||
public void notifyStart() {
|
||||
bus.post(new GetActivitiesTaskEvent(getContentUri(), true, null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,23 +6,28 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.Log;
|
||||
|
||||
import com.desmond.asyncmanager.AsyncManager;
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.SQLFunctions;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.api.twitter.model.Status;
|
||||
import org.mariotaku.twidere.model.RefreshTaskParam;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
|
||||
import org.mariotaku.twidere.task.CacheUsersStatusesTask;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.DataStoreUtils;
|
||||
|
@ -34,11 +39,14 @@ import org.mariotaku.twidere.util.TwitterWrapper;
|
|||
import org.mariotaku.twidere.util.UriUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
import org.mariotaku.twidere.util.message.GetStatusesTaskEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import edu.tsinghua.hotmobi.HotMobiLogger;
|
||||
import edu.tsinghua.hotmobi.model.RefreshEvent;
|
||||
import edu.tsinghua.hotmobi.model.TimelineType;
|
||||
|
@ -46,42 +54,35 @@ import edu.tsinghua.hotmobi.model.TimelineType;
|
|||
/**
|
||||
* Created by mariotaku on 16/1/2.
|
||||
*/
|
||||
public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWrapper.TwitterListResponse<Status>, List<TwitterWrapper.StatusListResponse>> {
|
||||
public abstract class GetStatusesTask extends TaskRunnable<RefreshTaskParam,
|
||||
List<TwitterWrapper.StatusListResponse>, Object> implements Constants {
|
||||
|
||||
private final long[] accountIds, maxIds, sinceIds;
|
||||
private final AsyncTwitterWrapper twitterWrapper;
|
||||
protected final Context context;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper preferences;
|
||||
@Inject
|
||||
protected Bus bus;
|
||||
@Inject
|
||||
protected ErrorInfoStore errorInfoStore;
|
||||
|
||||
public GetStatusesTask(AsyncTwitterWrapper twitterWrapper, final long[] accountIds,
|
||||
final long[] maxIds, final long[] sinceIds, final String tag) {
|
||||
super(twitterWrapper.getContext(), tag);
|
||||
this.twitterWrapper = twitterWrapper;
|
||||
this.accountIds = accountIds;
|
||||
this.maxIds = maxIds;
|
||||
this.sinceIds = sinceIds;
|
||||
public GetStatusesTask(Context context) {
|
||||
this.context = context;
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public abstract ResponseList<org.mariotaku.twidere.api.twitter.model.Status> getStatuses(Twitter twitter, Paging paging)
|
||||
public abstract ResponseList<Status> getStatuses(Twitter twitter, Paging paging)
|
||||
throws TwitterException;
|
||||
|
||||
@NonNull
|
||||
protected abstract Uri getDatabaseUri();
|
||||
protected abstract Uri getContentUri();
|
||||
|
||||
final boolean isMaxIdsValid() {
|
||||
return maxIds != null && maxIds.length == accountIds.length;
|
||||
}
|
||||
|
||||
final boolean isSinceIdsValid() {
|
||||
return sinceIds != null && sinceIds.length == accountIds.length;
|
||||
}
|
||||
|
||||
private void storeStatus(long accountId, List<org.mariotaku.twidere.api.twitter.model.Status> statuses,
|
||||
long sinceId, long maxId, boolean notify, int loadItemLimit) {
|
||||
private void storeStatus(long accountId, List<Status> statuses,
|
||||
long sinceId, long maxId, boolean notify) {
|
||||
if (statuses == null || statuses.isEmpty() || accountId <= 0) {
|
||||
return;
|
||||
}
|
||||
final Uri uri = getDatabaseUri();
|
||||
final Context context = twitterWrapper.getContext();
|
||||
final Uri uri = getContentUri();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final boolean noItemsBefore = DataStoreUtils.getStatusCount(context, uri, accountId) <= 0;
|
||||
final ContentValues[] values = new ContentValues[statuses.size()];
|
||||
|
@ -90,7 +91,7 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
|
|||
int minIdx = -1;
|
||||
boolean hasIntersection = false;
|
||||
for (int i = 0, j = statuses.size(); i < j; i++) {
|
||||
final org.mariotaku.twidere.api.twitter.model.Status status = statuses.get(i);
|
||||
final Status status = statuses.get(i);
|
||||
values[i] = ContentValuesCreator.createStatus(status, accountId);
|
||||
values[i].put(Statuses.INSERTED_DATE, System.currentTimeMillis());
|
||||
final long id = status.getId();
|
||||
|
@ -143,33 +144,23 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
|
|||
@TimelineType
|
||||
protected abstract String getTimelineType();
|
||||
|
||||
@SafeVarargs
|
||||
|
||||
@Override
|
||||
protected final void onProgressUpdate(TwitterWrapper.TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status>... values) {
|
||||
AsyncTaskUtils.executeTask(new CacheUsersStatusesTask(twitterWrapper.getContext()), values);
|
||||
public void callback(List<TwitterWrapper.StatusListResponse> result) {
|
||||
bus.post(new GetStatusesTaskEvent(getContentUri(), false, AsyncTwitterWrapper.getException(result)));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<TwitterWrapper.StatusListResponse> result) {
|
||||
super.onPostExecute(result);
|
||||
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), false, AsyncTwitterWrapper.getException(result)));
|
||||
@UiThread
|
||||
public void notifyStart() {
|
||||
bus.post(new GetStatusesTaskEvent(getContentUri(), true, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), true, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TwitterWrapper.StatusListResponse> doInBackground(final Object... params) {
|
||||
public List<TwitterWrapper.StatusListResponse> doLongOperation(final RefreshTaskParam param) {
|
||||
final long[] accountIds = param.getAccountIds(), maxIds = param.getMaxIds(), sinceIds = param.getSinceIds();
|
||||
final List<TwitterWrapper.StatusListResponse> result = new ArrayList<>();
|
||||
if (accountIds == null) return result;
|
||||
int idx = 0;
|
||||
final SharedPreferencesWrapper preferences = twitterWrapper.getPreferences();
|
||||
final Context context = twitterWrapper.getContext();
|
||||
final ErrorInfoStore errorInfoStore = twitterWrapper.getErrorInfoStore();
|
||||
final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
|
||||
for (final long accountId : accountIds) {
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true);
|
||||
|
@ -193,10 +184,13 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
|
|||
} else {
|
||||
sinceId = -1;
|
||||
}
|
||||
final List<org.mariotaku.twidere.api.twitter.model.Status> statuses = getStatuses(twitter, paging);
|
||||
final List<Status> statuses = getStatuses(twitter, paging);
|
||||
TwitterContentUtils.getStatusesWithQuoteData(twitter, statuses);
|
||||
storeStatus(accountId, statuses, sinceId, maxId, true, loadItemLimit);
|
||||
publishProgress(new TwitterWrapper.StatusListResponse(accountId, statuses));
|
||||
storeStatus(accountId, statuses, sinceId, maxId, true);
|
||||
// TODO cache related data and preload
|
||||
final CacheUsersStatusesTask cacheTask = new CacheUsersStatusesTask(context);
|
||||
cacheTask.setParams(new TwitterWrapper.StatusListResponse(accountId, statuses));
|
||||
AsyncManager.runBackgroundTask(cacheTask);
|
||||
errorInfoStore.remove(getErrorInfoKey(), accountId);
|
||||
} catch (final TwitterException e) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
|
@ -216,4 +210,5 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
|
|||
@NonNull
|
||||
protected abstract String getErrorInfoKey();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -40,12 +40,9 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.annotation.ReadPositionTag;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse;
|
||||
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
|
||||
import org.mariotaku.twidere.api.twitter.model.ErrorInfo;
|
||||
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
|
||||
|
@ -65,6 +62,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
|||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.model.RefreshTaskParam;
|
||||
import org.mariotaku.twidere.model.Response;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
|
@ -79,9 +77,11 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
|||
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
|
||||
import org.mariotaku.twidere.service.BackgroundOperationService;
|
||||
import org.mariotaku.twidere.task.GetActivitiesAboutMeTask;
|
||||
import org.mariotaku.twidere.task.GetActivitiesByFriendsTask;
|
||||
import org.mariotaku.twidere.task.GetHomeTimelineTask;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
|
||||
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
|
||||
import org.mariotaku.twidere.util.collection.LongSparseMap;
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
|
||||
|
@ -282,9 +282,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
return mContext;
|
||||
}
|
||||
|
||||
public boolean getHomeTimelineAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
|
||||
final GetHomeTimelineTask task = new GetHomeTimelineTask(this, accountIds, max_ids, since_ids);
|
||||
mAsyncTaskManager.add(task, true);
|
||||
public boolean getHomeTimelineAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final GetHomeTimelineTask task = new GetHomeTimelineTask(getContext());
|
||||
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
|
||||
task.notifyStart();
|
||||
AsyncManager.runBackgroundTask(task);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -525,69 +527,18 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
}.setResultHandler(bus));
|
||||
}
|
||||
|
||||
public void getActivitiesAboutMeAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
mAsyncTaskManager.add(new GetActivitiesTask(this, TASK_TAG_GET_MENTIONS, accountIds, maxIds, sinceIds) {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_INTERACTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveReadPosition(long accountId, Twitter twitter) {
|
||||
try {
|
||||
CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
|
||||
final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountIds);
|
||||
mReadStateManager.setPosition(tag, response.getCursor(), false);
|
||||
} catch (TwitterException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
|
||||
if (Utils.shouldUsePrivateAPIs(getContext(), accountId)) {
|
||||
return twitter.getActivitiesAboutMe(paging);
|
||||
}
|
||||
final ResponseList<Activity> activities = new ResponseList<>();
|
||||
for (org.mariotaku.twidere.api.twitter.model.Status status : twitter.getMentionsTimeline(paging)) {
|
||||
activities.add(Activity.fromMention(accountId, status));
|
||||
}
|
||||
return activities;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Activities.AboutMe.CONTENT_URI;
|
||||
}
|
||||
}, true);
|
||||
public void getActivitiesAboutMeAsync(final long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
final GetActivitiesTask task = new GetActivitiesAboutMeTask(getContext());
|
||||
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
|
||||
task.notifyStart();
|
||||
AsyncManager.runBackgroundTask(task);
|
||||
}
|
||||
|
||||
public void getActivitiesByFriendsAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
mAsyncTaskManager.add(new GetActivitiesTask(this, "get_activities_by_friends", accountIds, maxIds, sinceIds) {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_ACTIVITIES_BY_FRIENDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveReadPosition(long accountId, Twitter twitter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
|
||||
return twitter.getActivitiesByFriends(paging);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Activities.ByFriends.CONTENT_URI;
|
||||
}
|
||||
}, true);
|
||||
final GetActivitiesTask task = new GetActivitiesByFriendsTask(getContext());
|
||||
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
|
||||
task.notifyStart();
|
||||
AsyncManager.runBackgroundTask(task);
|
||||
}
|
||||
|
||||
public void setActivitiesAboutMeUnreadAsync(final long[] accountIds, final long cursor) {
|
||||
|
@ -2045,55 +1996,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
|
||||
}
|
||||
|
||||
static class GetHomeTimelineTask extends GetStatusesTask {
|
||||
|
||||
private AsyncTwitterWrapper twitterWrapper;
|
||||
|
||||
public GetHomeTimelineTask(AsyncTwitterWrapper asyncTwitterWrapper, final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
super(asyncTwitterWrapper, accountIds, maxIds, sinceIds, TASK_TAG_GET_HOME_TIMELINE);
|
||||
this.twitterWrapper = asyncTwitterWrapper;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ResponseList<org.mariotaku.twidere.api.twitter.model.Status> getStatuses(final Twitter twitter, final Paging paging)
|
||||
throws TwitterException {
|
||||
return twitter.getHomeTimeline(paging);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Uri getDatabaseUri() {
|
||||
return Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@TimelineType
|
||||
@Override
|
||||
protected String getTimelineType() {
|
||||
return TimelineType.HOME;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final List<StatusListResponse> result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
final Intent intent = new Intent(BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING);
|
||||
twitterWrapper.getContext().sendBroadcast(intent);
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected String getErrorInfoKey() {
|
||||
return ErrorInfoStore.KEY_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class GetLocalTrendsTask extends GetTrendsTask {
|
||||
|
||||
private final int woeid;
|
||||
|
@ -2511,4 +2413,5 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -182,13 +182,15 @@ public class DataStoreUtils implements Constants {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static long[] getNewestMessageIds(final Context context, final Uri uri, final long[] accountIds) {
|
||||
public static long[] getNewestMessageIds(@NonNull final Context context, @NonNull final Uri uri,
|
||||
@NonNull final long[] accountIds) {
|
||||
return getLongFieldArray(context, uri, accountIds, DirectMessages.ACCOUNT_ID, DirectMessages.MESSAGE_ID,
|
||||
new OrderBy(SQLFunctions.MAX(DirectMessages.MESSAGE_TIMESTAMP)));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static long[] getNewestStatusIds(final Context context, final Uri uri, final long[] accountIds) {
|
||||
public static long[] getNewestStatusIds(@NonNull final Context context, @NonNull final Uri uri,
|
||||
@NonNull final long[] accountIds) {
|
||||
return getLongFieldArray(context, uri, accountIds, Statuses.ACCOUNT_ID, Statuses.STATUS_ID,
|
||||
new OrderBy(SQLFunctions.MAX(Statuses.STATUS_TIMESTAMP)));
|
||||
}
|
||||
|
@ -353,6 +355,7 @@ public class DataStoreUtils implements Constants {
|
|||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static long[] getActivatedAccountIds(final Context context) {
|
||||
if (context == null) return new long[0];
|
||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
||||
|
|
|
@ -31,20 +31,15 @@ import static android.text.TextUtils.isEmpty;
|
|||
*/
|
||||
public class HttpClientFactory implements Constants {
|
||||
|
||||
public static RestHttpClient getDefaultHttpClient(final Context context, SharedPreferences prefs, Dns dns) {
|
||||
if (context == null) return null;
|
||||
return createHttpClient(context, prefs, dns);
|
||||
}
|
||||
|
||||
public static RestHttpClient createHttpClient(final Context context, final SharedPreferences prefs, Dns dns) {
|
||||
public static RestHttpClient createRestHttpClient(final Context context, final SharedPreferences prefs, Dns dns) {
|
||||
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
initDefaultHttpClient(context, prefs, builder, dns);
|
||||
initOkHttpClient(context, prefs, builder, dns);
|
||||
return new OkHttpRestClient(builder.build());
|
||||
}
|
||||
|
||||
public static void initDefaultHttpClient(Context context, SharedPreferences prefs, OkHttpClient.Builder builder, Dns dns) {
|
||||
public static void initOkHttpClient(Context context, SharedPreferences prefs, OkHttpClient.Builder builder, Dns dns) {
|
||||
updateHttpClientConfiguration(context, prefs, dns, builder);
|
||||
DebugModeUtils.initForHttpClient(builder);
|
||||
DebugModeUtils.initForOkHttpClient(builder);
|
||||
}
|
||||
|
||||
@SuppressLint("SSLCertificateSocketFactoryGetInsecure")
|
||||
|
@ -54,7 +49,7 @@ public class HttpClientFactory implements Constants {
|
|||
final long connectionTimeout = prefs.getInt(KEY_CONNECTION_TIMEOUT, 10);
|
||||
final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false);
|
||||
builder.connectTimeout(connectionTimeout, TimeUnit.SECONDS);
|
||||
builder.connectionPool(new ConnectionPool(0, 1, TimeUnit.MINUTES));
|
||||
builder.connectionPool(new ConnectionPool(5, 30, TimeUnit.SECONDS));
|
||||
if (enableProxy) {
|
||||
final String proxyType = prefs.getString(KEY_PROXY_TYPE, null);
|
||||
final String proxyHost = prefs.getString(KEY_PROXY_HOST, null);
|
||||
|
|
|
@ -135,7 +135,7 @@ public class ApplicationModule implements Constants {
|
|||
@Provides
|
||||
@Singleton
|
||||
public RestHttpClient restHttpClient(SharedPreferencesWrapper prefs, Dns dns) {
|
||||
return HttpClientFactory.getDefaultHttpClient(application, prefs, dns);
|
||||
return HttpClientFactory.createRestHttpClient(application, prefs, dns);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -51,6 +51,8 @@ import org.mariotaku.twidere.provider.TwidereDataProvider;
|
|||
import org.mariotaku.twidere.service.BackgroundOperationService;
|
||||
import org.mariotaku.twidere.service.RefreshService;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
|
||||
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
|
||||
import org.mariotaku.twidere.text.util.EmojiEditableFactory;
|
||||
import org.mariotaku.twidere.text.util.EmojiSpannableFactory;
|
||||
import org.mariotaku.twidere.util.MultiSelectEventHandler;
|
||||
|
@ -135,4 +137,8 @@ public interface GeneralComponent {
|
|||
void inject(TwitterAPIStatusesLoader loader);
|
||||
|
||||
void inject(MediaViewerActivity activity);
|
||||
|
||||
void inject(GetStatusesTask task);
|
||||
|
||||
void inject(GetActivitiesTask task);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import okhttp3.OkHttpClient;
|
|||
*/
|
||||
public class DebugModeUtils {
|
||||
|
||||
public static void initForHttpClient(final OkHttpClient.Builder builder) {
|
||||
public static void initForOkHttpClient(final OkHttpClient.Builder builder) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue