ExportLogsService.java

  1package eu.siacs.conversations.services;
  2
  3import android.app.NotificationManager;
  4import android.app.Service;
  5import android.content.Context;
  6import android.content.Intent;
  7import android.os.Build;
  8import android.os.IBinder;
  9import android.support.v4.app.NotificationCompat;
 10
 11import eu.siacs.conversations.R;
 12import eu.siacs.conversations.entities.Account;
 13import eu.siacs.conversations.entities.Conversation;
 14import eu.siacs.conversations.entities.Message;
 15import eu.siacs.conversations.persistance.DatabaseBackend;
 16import eu.siacs.conversations.persistance.FileBackend;
 17import eu.siacs.conversations.xmpp.jid.Jid;
 18
 19import java.io.BufferedWriter;
 20import java.io.File;
 21import java.io.FileWriter;
 22import java.io.IOException;
 23import java.text.SimpleDateFormat;
 24import java.util.Date;
 25import java.util.List;
 26import java.util.concurrent.atomic.AtomicBoolean;
 27
 28public class ExportLogsService extends Service {
 29
 30	private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
 31	private static final String DIRECTORY_STRING_FORMAT = FileBackend.getConversationsFileDirectory() + "/logs/%s";
 32	private static final String MESSAGE_STRING_FORMAT = "(%s) %s: %s\n";
 33	private static final int NOTIFICATION_ID = 1;
 34	private static AtomicBoolean running = new AtomicBoolean(false);
 35
 36	@Override
 37	public int onStartCommand(Intent intent, int flags, int startId) {
 38		if (running.compareAndSet(false, true)) {
 39			new Thread(
 40					new Runnable() {
 41						DatabaseBackend databaseBackend = DatabaseBackend.getInstance(getBaseContext());
 42						List<Account> accounts = databaseBackend.getAccounts();
 43
 44						@Override
 45						public void run() {
 46							List<Conversation> conversations = databaseBackend.getConversations(Conversation.STATUS_AVAILABLE);
 47							conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_ARCHIVED));
 48
 49							NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 50							NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext());
 51							mBuilder.setContentTitle(getString(R.string.notification_export_logs_title))
 52									.setSmallIcon(R.drawable.ic_import_export_white_24dp)
 53									.setProgress(conversations.size(), 0, false);
 54							startForeground(NOTIFICATION_ID, mBuilder.build());
 55
 56							int progress = 0;
 57							for (Conversation conversation : conversations) {
 58								writeToFile(conversation);
 59								progress++;
 60								mBuilder.setProgress(conversations.size(), progress, false);
 61								mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
 62							}
 63
 64							running.set(false);
 65							stopForeground(true);
 66						}
 67
 68						private void writeToFile(Conversation conversation) {
 69							Jid accountJid = resolveAccountUuid(conversation.getAccountUuid());
 70							Jid contactJid = conversation.getJid();
 71
 72							File dir = new File(String.format(DIRECTORY_STRING_FORMAT,
 73									accountJid.toBareJid().toString()));
 74							dir.mkdirs();
 75
 76							BufferedWriter bw = null;
 77							try {
 78								for (Message message : databaseBackend.getMessagesIterable(conversation)) {
 79									if (message.getType() == Message.TYPE_TEXT || message.hasFileOnRemoteHost()) {
 80										String date = simpleDateFormat.format(new Date(message.getTimeSent()));
 81										if (bw == null) {
 82											bw = new BufferedWriter(new FileWriter(
 83													new File(dir, contactJid.toBareJid().toString() + ".txt")));
 84										}
 85										String jid = null;
 86										switch (message.getStatus()) {
 87											case Message.STATUS_RECEIVED:
 88												jid = getMessageCounterpart(message);
 89												break;
 90											case Message.STATUS_SEND:
 91											case Message.STATUS_SEND_RECEIVED:
 92											case Message.STATUS_SEND_DISPLAYED:
 93												jid = accountJid.toBareJid().toString();
 94												break;
 95										}
 96										if (jid != null) {
 97											String body = message.hasFileOnRemoteHost() ? message.getFileParams().url.toString() : message.getBody();
 98											bw.write(String.format(MESSAGE_STRING_FORMAT, date, jid,
 99													body.replace("\\\n", "\\ \n").replace("\n", "\\ \n")));
100										}
101									}
102								}
103							} catch (IOException e) {
104								e.printStackTrace();
105							} finally {
106								try {
107									if (bw != null) {
108										bw.close();
109									}
110								} catch (IOException e1) {
111									e1.printStackTrace();
112								}
113							}
114						}
115
116						private Jid resolveAccountUuid(String accountUuid) {
117							for (Account account : accounts) {
118								if (account.getUuid().equals(accountUuid)) {
119									return account.getJid();
120								}
121							}
122							return null;
123						}
124
125						private String getMessageCounterpart(Message message) {
126							String trueCounterpart = (String) message.getContentValues().get(Message.TRUE_COUNTERPART);
127							if (trueCounterpart != null) {
128								return trueCounterpart;
129							} else {
130								return message.getCounterpart().toString();
131							}
132						}
133					}).start();
134		}
135		return START_STICKY;
136	}
137
138	@Override
139	public IBinder onBind(Intent intent) {
140		return null;
141	}
142}