package com.kenny.openimgur.services;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import com.google.android.apps.muzei.api.Artwork;
import com.google.android.apps.muzei.api.RemoteMuzeiArtSource;
import com.kenny.openimgur.R;
import com.kenny.openimgur.activities.MuzeiSettingsActivity;
import com.kenny.openimgur.api.ApiClient;
import com.kenny.openimgur.api.responses.GalleryResponse;
import com.kenny.openimgur.classes.ImgurBaseObject;
import com.kenny.openimgur.classes.ImgurFilters;
import com.kenny.openimgur.classes.ImgurPhoto;
import com.kenny.openimgur.classes.OpengurApp;
import com.kenny.openimgur.util.LogUtil;
import com.kenny.openimgur.util.NetworkUtils;
import com.kenny.openimgur.util.SqlHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import retrofit2.Call;
import retrofit2.Response;
/**
* Created by Kenny-PC on 6/21/2015.
*/
public class ImgurMuzeiService extends RemoteMuzeiArtSource {
private static final String TAG = "ImgurMuzeiService";
// If unable to get an image, DickButt will be shown, dealwithit.gif
private static final String FALLBACK_URL = "http://i.imgur.com/myiMdIq.jpeg";
private static final String FALLBACK_SUBREDDIT = "aww";
// 8 is aww
private static final String FALLBACK_TOPIC_ID = "8";
private static final Random sRandom = new Random();
private static final int RETRY_ATTEMPTS = 5;
@Nullable
private String mSubreddit = null;
public ImgurMuzeiService() {
super(TAG);
}
@Override
public void onCreate() {
super.onCreate();
setUserCommands(BUILTIN_COMMAND_ID_NEXT_ARTWORK);
}
@Override
protected void onTryUpdate(int reason) throws RetryException {
Context context = getApplicationContext();
if (NetworkUtils.hasDataSaver(context)) {
LogUtil.w(TAG, "Data saver enabled, not updating");
return;
}
OpengurApp app = OpengurApp.getInstance(context);
SharedPreferences pref = app.getPreferences();
boolean allowNSFW = pref.getBoolean(MuzeiSettingsActivity.KEY_NSFW, false);
boolean wifiOnly = pref.getBoolean(MuzeiSettingsActivity.KEY_WIFI, true);
String source = pref.getString(MuzeiSettingsActivity.KEY_SOURCE, MuzeiSettingsActivity.SOURCE_VIRAL);
String updateInterval = pref.getString(MuzeiSettingsActivity.KEY_UPDATE, MuzeiSettingsActivity.UPDATE_3_HOURS);
if (wifiOnly && !NetworkUtils.isConnectedToWiFi(context)) {
LogUtil.w(TAG, "Not connected to WiFi when user requires it");
return;
}
String url;
String title;
String byline;
Uri uri;
List<ImgurPhoto> photos = fetchImages(source, pref, allowNSFW);
if (photos != null && !photos.isEmpty()) {
ImgurPhoto photo = photos.get(sRandom.nextInt(photos.size()));
SqlHelper sql = SqlHelper.getInstance(context);
if (sql.getMuzeiLastSeen(photo.getLink()) != -1) {
// We have seen this image already, lets try to get another
LogUtil.v(TAG, "Got an image we have already seen, going to try for another");
int retryCount = 0;
while (retryCount < RETRY_ATTEMPTS) {
photo = photos.get(sRandom.nextInt(photos.size()));
if (sql.getMuzeiLastSeen(photo.getLink()) == -1) {
LogUtil.v(TAG, "Received a valid image, retry count at " + retryCount);
break;
}
LogUtil.v(TAG, "Received another duplicate, retry count at " + retryCount);
retryCount++;
}
} else {
LogUtil.v(TAG, "Link does not exist in database");
}
sql.addMuzeiLink(photo.getLink());
url = photo.getLink();
title = photo.getTitle();
if (source.equals(MuzeiSettingsActivity.SOURCE_REDDIT)) {
byline = TextUtils.isEmpty(mSubreddit) ? pref.getString(MuzeiSettingsActivity.KEY_INPUT, FALLBACK_SUBREDDIT) : mSubreddit;
mSubreddit = null;
} else {
byline = TextUtils.isEmpty(photo.getAccount()) ? "?????" : photo.getAccount();
}
} else {
url = FALLBACK_URL;
title = getString(R.string.muzei_error_title);
byline = getString(R.string.muzei_error_byline);
}
uri = Uri.parse(url);
publishArtwork(new Artwork.Builder()
.imageUri(uri)
.title(title)
.byline(byline)
.viewIntent(new Intent(Intent.ACTION_VIEW, uri))
.build());
scheduleUpdate(System.currentTimeMillis() + getNextUpdateTime(updateInterval));
}
/**
* Returns the time until the next update
*
* @param updateInterval The preference value for the next update
* @return
*/
private long getNextUpdateTime(String updateInterval) {
if (MuzeiSettingsActivity.UPDATE_1_HOUR.equals(updateInterval)) {
return DateUtils.HOUR_IN_MILLIS;
} else if (MuzeiSettingsActivity.UPDATE_6_HOURS.equals(updateInterval)) {
return DateUtils.HOUR_IN_MILLIS * 6;
} else if (MuzeiSettingsActivity.UPDATE_12_HOURS.equals(updateInterval)) {
return DateUtils.HOUR_IN_MILLIS * 12;
} else if (MuzeiSettingsActivity.UPDATE_24_HOURS.equals(updateInterval)) {
return DateUtils.DAY_IN_MILLIS;
}
return DateUtils.HOUR_IN_MILLIS * 3;
}
@Nullable
private List<ImgurPhoto> fetchImages(String source, SharedPreferences pref, boolean allowNSFW) {
Response<GalleryResponse> response = null;
Call<GalleryResponse> call;
try {
if (MuzeiSettingsActivity.SOURCE_REDDIT.equals(source)) {
String query = pref.getString(MuzeiSettingsActivity.KEY_INPUT, FALLBACK_SUBREDDIT);
String[] split = query.split(",");
if (split.length > 1) {
query = split[sRandom.nextInt(split.length)];
}
mSubreddit = query.replaceAll("\\s", "");
call = ApiClient.getService().getSubReddit(mSubreddit, ImgurFilters.RedditSort.TIME.getSort(), 0);
} else if (MuzeiSettingsActivity.SOURCE_USER_SUB.equals(source)) {
call = ApiClient.getService().getGallery(ImgurFilters.GallerySection.USER.getSection(), ImgurFilters.GallerySort.VIRAL.getSort(), 0, false);
} else if (MuzeiSettingsActivity.SOURCE_TOPICS.equals(source)) {
int topicId = Integer.valueOf(pref.getString(MuzeiSettingsActivity.KEY_TOPIC, FALLBACK_TOPIC_ID));
call = ApiClient.getService().getTopic(topicId, ImgurFilters.GallerySort.VIRAL.getSort(), 0);
} else {
call = ApiClient.getService().getGallery(ImgurFilters.GallerySection.HOT.getSection(), ImgurFilters.GallerySort.TIME.getSort(), 0, false);
}
response = call.execute();
} catch (Exception ex) {
Log.e(TAG, "Error fetching images for muzei", ex);
}
if (response != null && response.body() != null && !response.body().data.isEmpty()) {
// Go through the responses and exclude albums, gifs, and check NSFW status
List<ImgurPhoto> photos = new ArrayList<>();
for (ImgurBaseObject obj : response.body().data) {
if (obj instanceof ImgurPhoto && !((ImgurPhoto) obj).isAnimated() && (allowNSFW || !obj.isNSFW())) {
photos.add((ImgurPhoto) obj);
}
}
return photos;
}
return null;
}
}