package org.igarape.copcast.service;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.igarape.copcast.R;
import org.igarape.copcast.utils.FileUtils;
import org.igarape.copcast.utils.HttpResponseCallback;
import org.igarape.copcast.utils.NetworkUtils;
import org.igarape.copcast.utils.ServiceUtils;
import org.igarape.copcast.views.MainActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* Created by bruno on 11/14/14.
*/
public class UploadService extends Service {
private static final String TAG = UploadService.class.getName();
public static final String UPLOAD_PROGRESS_ACTION = "org.igarape.copcast.UPLOAD_PROGRESS";
public static final String FILE_SIZE = "FILE_SIZE";
public static final String CANCEL_UPLOAD_ACTION = "org.igarape.copcast.CANCEL_UPLOAD";
public static final String COMPLETED_UPLOAD_ACTION = "org.igarape.copcast.COMPLETED_UPLOAD";
private int mId = 3;
private List<String> users;
private final GenericExtFilter filter = new GenericExtFilter(".mp4");
private ArrayList<File> videos;
private DateFormat df = new SimpleDateFormat(FileUtils.DATE_FORMAT);
private LocalBroadcastManager broadcaster;
private Intent intent;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.intent = intent;
final Intent resultIntent = new Intent(this, MainActivity.class);
final Context context = getApplicationContext();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setContentTitle(getString(R.string.notification_upload_title))
.setContentText(getString(R.string.notification_upload_description))
.setSmallIcon(R.drawable.ic_launcher);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_NO_CREATE
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
users = new ArrayList<String>();
Collections.addAll(users, FileUtils.getUserFolders());
broadcaster = LocalBroadcastManager.getInstance(this);
if (!users.isEmpty()){
uploadUserData();
}
return super.onStartCommand(intent, flags, startId);
}
public void sendUpdateToUI(Long size) {
Intent intent = new Intent(UPLOAD_PROGRESS_ACTION);
if(size != null)
intent.putExtra(FILE_SIZE, size);
broadcaster.sendBroadcast(intent);
}
private void uploadUserData() {
if (!ServiceUtils.isMyServiceRunning(UploadService.class, getApplicationContext())){
return;
}
if (!NetworkUtils.canUpload(getApplicationContext(), this.intent)) {
sendCancelToUI();
this.stopSelf();
return;
}
if (users.isEmpty()){
sendCompletedToUI();
this.stopSelf();
return;
}
String userLogin = users.remove(0);
String path = FileUtils.getPath(userLogin);
uploadLocations(userLogin);
uploadHistories(userLogin);
File dir = new File(path);
File[] files = dir.listFiles(filter);
if (files != null && files.length > 0) {
videos = new ArrayList<File>(Arrays.asList(files));
if (!videos.isEmpty()) {
File nextVideo = videos.remove(0);
uploadVideo(nextVideo, userLogin);
} else {
uploadUserData();
}
}
}
private void uploadLocations(String userLogin) {
final File file = new File(FileUtils.getLocationsFilePath(userLogin));
if (!file.exists()) {
return;
}
FileInputStream is = null;
try {
is = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
JSONArray locations = new JSONArray();
String line;
while ((line = br.readLine()) != null) {
JSONObject json = new JSONObject(line);
if (json.getString("lat") != null && json.getString("lat").length() > 0) {
locations.put(json);
}
}
NetworkUtils.post(getApplicationContext(),"/locations/"+userLogin, locations, new HttpResponseCallback() {
@Override
public void unauthorized() {
Log.e(TAG, "locations unauthorized");
}
@Override
public void failure(int statusCode) {
Log.e(TAG, "locations failure - statusCode: "+statusCode);
}
@Override
public void success(JSONObject response) {
file.delete();
}
@Override
public void noConnection() {
Log.e(TAG, "locations noConnection");
}
@Override
public void badConnection() {
Log.e(TAG, "locations badConnection");
}
@Override
public void badRequest() {
Log.e(TAG, "locations badRequest");
}
@Override
public void badResponse() {
Log.e(TAG, "locations badResponse");
}
});
} catch (java.io.IOException e) {
Log.e(TAG, "location file error", e);
} catch (JSONException e) {
Log.e(TAG, "location file error", e);
}
}
private void uploadHistories(String userLogin) {
final File file = new File(FileUtils.getHistoriesFilePath(userLogin));
if (!file.exists()) {
return;
}
FileInputStream is = null;
try {
is = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
JSONArray histories = new JSONArray();
String line;
while ((line = br.readLine()) != null) {
JSONObject json = new JSONObject(line);
if (json.getString("previousState").length() > 0) {
histories.put(json);
}
}
NetworkUtils.post(getApplicationContext(),"/histories/"+userLogin, histories, new HttpResponseCallback() {
@Override
public void unauthorized() {
Log.e(TAG, "histories unauthorized");
}
@Override
public void failure(int statusCode) {
Log.e(TAG, "histories failure - statusCode: "+statusCode);
}
@Override
public void success(JSONObject response) {
file.delete();
}
@Override
public void noConnection() {
Log.e(TAG, "histories noConnection");
}
@Override
public void badConnection() {
Log.e(TAG, "histories badConnection");
}
@Override
public void badRequest() {
Log.e(TAG, "histories badRequest");
}
@Override
public void badResponse() {
Log.e(TAG, "histories badResponse");
}
});
} catch (java.io.IOException e) {
Log.e(TAG, "location file error", e);
} catch (JSONException e) {
Log.e(TAG, "location file error", e);
}
}
private void uploadVideo(final File nextVideo, final String userLogin) {
if (!ServiceUtils.isMyServiceRunning(UploadService.class, getApplicationContext())){
return;
}
if (!NetworkUtils.canUpload(getApplicationContext(), this.intent)) {
sendCancelToUI();
this.stopSelf();
return;
}
if (nextVideo.exists()) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("date", df.format(new Date(nextVideo.lastModified()))));
NetworkUtils.post(getApplicationContext(), "/videos/" + userLogin, params, nextVideo, new HttpResponseCallback() {
@Override
public void unauthorized() {
Log.e(TAG, "unauthorized");
}
@Override
public void failure(int statusCode) {
if (!videos.isEmpty()){
uploadVideo(videos.remove(0), userLogin);
} else {
uploadUserData();
}
}
@Override
public void success(JSONObject response) {
sendUpdateToUI(nextVideo.length());
nextVideo.delete();
if (!videos.isEmpty()){
uploadVideo(videos.remove(0), userLogin);
} else {
uploadUserData();
}
}
@Override
public void noConnection() {
Log.e(TAG, "noConnection");
}
@Override
public void badConnection() {
Log.e(TAG, "badConnection");
}
@Override
public void badRequest() {
Log.e(TAG, "badRequest");
}
@Override
public void badResponse() {
Log.e(TAG, "badResponse");
}
});
}
}
private void sendCancelToUI() {
Intent intent = new Intent(CANCEL_UPLOAD_ACTION);
broadcaster.sendBroadcast(intent);
}
private void sendCompletedToUI() {
Intent intent = new Intent(COMPLETED_UPLOAD_ACTION);
broadcaster.sendBroadcast(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(mId);
}
class GenericExtFilter implements FilenameFilter {
private String ext;
public GenericExtFilter(String ext) {
this.ext = ext;
}
public boolean accept(File dir, String name) {
return (name.endsWith(ext));
}
}
}