aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs')
-rw-r--r--src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java6
-rw-r--r--src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java2
-rw-r--r--src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java1
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java38
-rw-r--r--src/main/java/eu/siacs/conversations/services/ExportLogsService.java142
-rw-r--r--src/main/java/eu/siacs/conversations/services/NotificationService.java4
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ExportLogsPreference.java29
7 files changed, 216 insertions, 6 deletions
diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
index 69bb18036..879a56802 100644
--- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java
@@ -36,8 +36,8 @@ public abstract class AbstractGenerator {
"urn:xmpp:receipts"
};
private String mVersion = null;
- public final String IDENTITY_NAME = "Conversations";
- public final String IDENTITY_TYPE = "phone";
+ protected final String IDENTITY_NAME = "Conversations";
+ protected final String IDENTITY_TYPE = "phone";
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
@@ -54,7 +54,7 @@ public abstract class AbstractGenerator {
return this.mVersion;
}
- protected String getIdentityName() {
+ public String getIdentityName() {
return IDENTITY_NAME + " " + getIdentityVersion();
}
diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
index 0d202bb92..5fa7bf816 100644
--- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
+++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java
@@ -181,6 +181,7 @@ public class HttpDownloadConnection implements Transferable {
changeStatus(STATUS_CHECKING);
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
connection.setRequestMethod("HEAD");
+ connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName());
if (connection instanceof HttpsURLConnection) {
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
}
@@ -236,6 +237,7 @@ public class HttpDownloadConnection implements Transferable {
if (connection instanceof HttpsURLConnection) {
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
}
+ connection.setRequestProperty("User-Agent",mXmppConnectionService.getIqGenerator().getIdentityName());
connection.connect();
is = new BufferedInputStream(connection.getInputStream());
file.getParentFile().mkdirs();
diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
index 38e25e7af..3aa288813 100644
--- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
+++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
@@ -165,6 +165,7 @@ public class HttpUploadConnection implements Transferable {
connection.setRequestMethod("PUT");
connection.setFixedLengthStreamingMode((int) file.getExpectedSize());
connection.setRequestProperty("Content-Type", mime == null ? "application/octet-stream" : mime);
+ connection.setRequestProperty("User-Agent",mXmppConnectionService.getIqGenerator().getIdentityName());
connection.setDoOutput(true);
connection.connect();
os = connection.getOutputStream();
diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
index d420c1cd8..be827929c 100644
--- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -21,6 +21,7 @@ import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -407,6 +408,43 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
+ public Iterable<Message> getMessagesIterable(final Conversation conversation){
+ return new Iterable<Message>() {
+ @Override
+ public Iterator<Message> iterator() {
+ class MessageIterator implements Iterator<Message>{
+ SQLiteDatabase db = getReadableDatabase();
+ String[] selectionArgs = { conversation.getUuid() };
+ Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
+ + "=?", selectionArgs, null, null, Message.TIME_SENT
+ + " ASC", null);
+
+ public MessageIterator() {
+ cursor.moveToFirst();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !cursor.isAfterLast();
+ }
+
+ @Override
+ public Message next() {
+ Message message = Message.fromCursor(cursor);
+ cursor.moveToNext();
+ return message;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ return new MessageIterator();
+ }
+ };
+ }
+
public Conversation findConversation(final Account account, final Jid contactJid) {
SQLiteDatabase db = this.getReadableDatabase();
String[] selectionArgs = { account.getUuid(),
diff --git a/src/main/java/eu/siacs/conversations/services/ExportLogsService.java b/src/main/java/eu/siacs/conversations/services/ExportLogsService.java
new file mode 100644
index 000000000..8501c04ad
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/services/ExportLogsService.java
@@ -0,0 +1,142 @@
+package eu.siacs.conversations.services;
+
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.IBinder;
+import android.support.v4.app.NotificationCompat;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.persistance.DatabaseBackend;
+import eu.siacs.conversations.persistance.FileBackend;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class ExportLogsService extends Service {
+
+ private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ private static final String DIRECTORY_STRING_FORMAT = FileBackend.getConversationsFileDirectory() + "/logs/%s";
+ private static final String MESSAGE_STRING_FORMAT = "(%s) %s: %s\n";
+ private static final int NOTIFICATION_ID = 1;
+ private static AtomicBoolean running = new AtomicBoolean(false);
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (running.compareAndSet(false, true)) {
+ new Thread(
+ new Runnable() {
+ DatabaseBackend databaseBackend = DatabaseBackend.getInstance(getBaseContext());
+ List<Account> accounts = databaseBackend.getAccounts();
+
+ @Override
+ public void run() {
+ List<Conversation> conversations = databaseBackend.getConversations(Conversation.STATUS_AVAILABLE);
+ conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_ARCHIVED));
+
+ NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext());
+ mBuilder.setContentTitle(getString(R.string.notification_export_logs_title))
+ .setSmallIcon(R.drawable.ic_import_export_white_24dp)
+ .setProgress(conversations.size(), 0, false);
+ startForeground(NOTIFICATION_ID, mBuilder.build());
+
+ int progress = 0;
+ for (Conversation conversation : conversations) {
+ writeToFile(conversation);
+ progress++;
+ mBuilder.setProgress(conversations.size(), progress, false);
+ mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
+ }
+
+ running.set(false);
+ stopForeground(true);
+ }
+
+ private void writeToFile(Conversation conversation) {
+ Jid accountJid = resolveAccountUuid(conversation.getAccountUuid());
+ Jid contactJid = conversation.getJid();
+
+ File dir = new File(String.format(DIRECTORY_STRING_FORMAT,
+ accountJid.toBareJid().toString()));
+ dir.mkdirs();
+
+ BufferedWriter bw = null;
+ try {
+ for (Message message : databaseBackend.getMessagesIterable(conversation)) {
+ if (message.getType() == Message.TYPE_TEXT || message.hasFileOnRemoteHost()) {
+ String date = simpleDateFormat.format(new Date(message.getTimeSent()));
+ if (bw == null) {
+ bw = new BufferedWriter(new FileWriter(
+ new File(dir, contactJid.toBareJid().toString() + ".txt")));
+ }
+ String jid = null;
+ switch (message.getStatus()) {
+ case Message.STATUS_RECEIVED:
+ jid = getMessageCounterpart(message);
+ break;
+ case Message.STATUS_SEND:
+ case Message.STATUS_SEND_RECEIVED:
+ case Message.STATUS_SEND_DISPLAYED:
+ jid = accountJid.toBareJid().toString();
+ break;
+ }
+ if (jid != null) {
+ String body = message.hasFileOnRemoteHost() ? message.getFileParams().url.toString() : message.getBody();
+ bw.write(String.format(MESSAGE_STRING_FORMAT, date, jid,
+ body.replace("\\\n", "\\ \n").replace("\n", "\\ \n")));
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (bw != null) {
+ bw.close();
+ }
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+
+ private Jid resolveAccountUuid(String accountUuid) {
+ for (Account account : accounts) {
+ if (account.getUuid().equals(accountUuid)) {
+ return account.getJid();
+ }
+ }
+ return null;
+ }
+
+ private String getMessageCounterpart(Message message) {
+ String trueCounterpart = (String) message.getContentValues().get(Message.TRUE_COUNTERPART);
+ if (trueCounterpart != null) {
+ return trueCounterpart;
+ } else {
+ return message.getCounterpart().toString();
+ }
+ }
+ }).start();
+ }
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java
index 2e13964ed..ec70296a0 100644
--- a/src/main/java/eu/siacs/conversations/services/NotificationService.java
+++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java
@@ -497,16 +497,14 @@ public class NotificationService {
final int cancelIcon;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setCategory(Notification.CATEGORY_SERVICE);
- mBuilder.setSmallIcon(R.drawable.ic_import_export_white_24dp);
cancelIcon = R.drawable.ic_cancel_white_24dp;
} else {
- mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export);
cancelIcon = R.drawable.ic_action_cancel;
}
+ mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp);
mBuilder.addAction(cancelIcon,
mXmppConnectionService.getString(R.string.disable_foreground_service),
createDisableForeground());
- setNotificationColor(mBuilder);
return mBuilder.build();
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ExportLogsPreference.java b/src/main/java/eu/siacs/conversations/ui/ExportLogsPreference.java
new file mode 100644
index 000000000..a4e178bd3
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/ui/ExportLogsPreference.java
@@ -0,0 +1,29 @@
+package eu.siacs.conversations.ui;
+
+import android.content.Context;
+import android.content.Intent;
+import android.preference.Preference;
+import android.util.AttributeSet;
+
+import eu.siacs.conversations.services.ExportLogsService;
+
+public class ExportLogsPreference extends Preference {
+
+ public ExportLogsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public ExportLogsPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ExportLogsPreference(Context context) {
+ super(context);
+ }
+
+ protected void onClick() {
+ final Intent startIntent = new Intent(getContext(), ExportLogsService.class);
+ getContext().startService(startIntent);
+ super.onClick();
+ }
+} \ No newline at end of file