package de.westnordost.streetcomplete.data;
import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Provider;
import de.westnordost.osmapi.common.errors.OsmAuthorizationException;
import de.westnordost.osmapi.common.errors.OsmConnectionException;
import de.westnordost.streetcomplete.ApplicationConstants;
import de.westnordost.streetcomplete.Injector;
import de.westnordost.streetcomplete.data.osm.upload.OsmQuestChangesUpload;
import de.westnordost.streetcomplete.data.osmnotes.CreateNoteUpload;
import de.westnordost.streetcomplete.data.osmnotes.OsmNoteQuestChangesUpload;
import de.westnordost.streetcomplete.oauth.OAuth;
/** Collects and uploads all changes the user has done: notes he left, comments he left on existing
* notes and quests he answered */
public class QuestChangesUploadService extends IntentService
{
public static final String
ACTION_ERROR = "de.westnordost.QuestChangesUploadService.ERROR",
IS_AUTH_FAILED = "authFailed",
IS_VERSION_BANNED = "banned",
IS_CONNECTION_ERROR = "connectionError",
EXCEPTION = "exception";
public static final String
ACTION_FINISHED = "de.westnordost.QuestChangesUploadService.FINISHED";
private static final String TAG = "QuestChangesUpload";
private static Boolean banned = null;
private static String banReason = null;
@Inject Provider<OsmNoteQuestChangesUpload> noteQuestUploadProvider;
@Inject Provider<OsmQuestChangesUpload> questUploadProvider;
@Inject Provider<CreateNoteUpload> createNoteUploadProvider;
@Inject SharedPreferences prefs;
private AtomicBoolean cancelState;
public QuestChangesUploadService()
{
super(TAG);
Injector.instance.getApplicationComponent().inject(this);
}
@Override public void onCreate()
{
super.onCreate();
cancelState = new AtomicBoolean(false);
}
@Override public void onDestroy()
{
cancelState.set(true);
super.onDestroy();
}
@Override protected void onHandleIntent(Intent intent)
{
if(cancelState.get()) return;
if(isBanned())
{
Log.i(TAG, "This version is banned from making any changes!");
Intent errorIntent = new Intent(ACTION_ERROR);
errorIntent.putExtra(IS_VERSION_BANNED, true);
send(errorIntent);
return;
}
// let's fail early in case of no authorization
if(!OAuth.isAuthorized(prefs))
{
Log.i(TAG, "User is not authorized");
Intent errorIntent = new Intent(ACTION_ERROR);
errorIntent.putExtra(IS_AUTH_FAILED, true);
send(errorIntent);
return;
}
Log.i(TAG, "Starting upload changes");
try
{
OsmNoteQuestChangesUpload noteQuestUpload = noteQuestUploadProvider.get();
noteQuestUpload.upload(cancelState);
if (cancelState.get()) return;
OsmQuestChangesUpload osmQuestUpload = questUploadProvider.get();
osmQuestUpload.upload(cancelState);
if (cancelState.get()) return;
CreateNoteUpload createNoteUpload = createNoteUploadProvider.get();
createNoteUpload.upload(cancelState);
}
catch (OsmConnectionException e)
{
Log.i(TAG, "No connection");
Intent errorIntent = new Intent(ACTION_ERROR);
errorIntent.putExtra(IS_CONNECTION_ERROR, true);
errorIntent.putExtra(EXCEPTION, e);
send(errorIntent);
}
catch (OsmAuthorizationException e)
{
Log.i(TAG, "User is not authorized");
Intent errorIntent = new Intent(ACTION_ERROR);
errorIntent.putExtra(IS_AUTH_FAILED, true);
errorIntent.putExtra(EXCEPTION, e);
send(errorIntent);
}
catch (Exception e)
{
Log.e(TAG, "Unable to upload changes", e);
Intent errorIntent = new Intent(ACTION_ERROR);
errorIntent.putExtra(EXCEPTION, e);
send(errorIntent);
}
send(new Intent(ACTION_FINISHED));
Log.i(TAG, "Finished upload changes");
}
private static boolean isBanned()
{
if(banned == null) checkBanned();
return banned;
}
private static void checkBanned()
{
HttpURLConnection connection = null;
try
{
URL url = new URL("http://www.westnordost.de/streetcomplete/banned_versions.txt");
connection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
{
if(line.startsWith(ApplicationConstants.USER_AGENT))
{
banned = true;
return;
}
}
}
catch(IOException e)
{
// if there is an io exception, never mind then...! (The unreachability of the above
// internet address should not lead to this app being unusable!)
}
finally
{
if (connection != null) connection.disconnect();
}
banned = false;
}
private void send(Intent intent)
{
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}