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