From 2090b3c7e1169e942dd78d3940d612e58cc64607 Mon Sep 17 00:00:00 2001 From: "Markus M. May" Date: Mon, 23 Jul 2018 20:58:20 +0200 Subject: [PATCH] First draft --- .../nightscout/androidaps/MainActivity.java | 15 ++ .../info/nightscout/androidaps/MainApp.java | 8 +- .../info/nightscout/utils/LoggerUtils.java | 171 ++++++++++++++++++ app/src/main/res/menu/menu_main.xml | 4 + app/src/main/res/values/strings.xml | 1 + .../java/info/nightscout/MainAppTest.java | 3 +- .../nightscout/utils/LoggerUtilsTest.java | 40 ++++ .../AndroidAPS.2018-01-01_01-01-00.1.zip | 0 .../AndroidAPS.2018-01-02_01-01-00.1.zip | 0 .../AndroidAPS.2018-01-03_01-01-00.1.zip | 0 app/src/test/res/logger/AndroidAPS.log | 0 11 files changed, 235 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/info/nightscout/utils/LoggerUtils.java create mode 100644 app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip create mode 100644 app/src/test/res/logger/AndroidAPS.log diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 8a19a05f4d..e7cc073166 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -38,6 +38,9 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.util.List; + import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventFeatureRunning; @@ -53,6 +56,7 @@ import info.nightscout.utils.AndroidPermission; import info.nightscout.utils.ImportExportPrefs; import info.nightscout.utils.LocaleHelper; import info.nightscout.utils.LogDialog; +import info.nightscout.utils.LoggerUtils; import info.nightscout.utils.OKDialog; import info.nightscout.utils.PasswordProtection; import info.nightscout.utils.SP; @@ -391,6 +395,17 @@ public class MainActivity extends AppCompatActivity { return true; case R.id.nav_show_logcat: LogDialog.showLogcat(this); + return true; + case R.id.nav_export_log: + String recipient = "mmay@gmx.net"; + + String logDirectory = LoggerUtils.getLogDirectory(); + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + String zipName = LoggerUtils.constructName(); + File zip = LoggerUtils.zipLogs(zipName, logDirectory, logs); + Intent emailIntent = LoggerUtils.sendMail(zip, recipient, "Log Export"); + startActivity(Intent.createChooser(emailIntent , "Send email...")); + return true; case R.id.nav_about: AlertDialog.Builder builder = new AlertDialog.Builder(this); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index dbb6ddee8b..de800b8468 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -78,6 +78,7 @@ import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.receivers.KeepAliveReceiver; import info.nightscout.androidaps.receivers.NSAlarmReceiver; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.LoggerUtils; import info.nightscout.utils.NSUpload; import io.fabric.sdk.android.Fabric; @@ -127,7 +128,7 @@ public class MainApp extends Application { log.info("Version: " + BuildConfig.VERSION_NAME); log.info("BuildVersion: " + BuildConfig.BUILDVERSION); - String extFilesDir = this.getLogDirectory(); + String extFilesDir = LoggerUtils.getLogDirectory(); File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode"); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); @@ -388,11 +389,6 @@ public class MainApp extends Application { return devBranch; } - public String getLogDirectory() { - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - return lc.getProperty("EXT_FILES_DIR"); - } - @Override public void onTerminate() { super.onTerminate(); diff --git a/app/src/main/java/info/nightscout/utils/LoggerUtils.java b/app/src/main/java/info/nightscout/utils/LoggerUtils.java new file mode 100644 index 0000000000..ec5f927cb4 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/LoggerUtils.java @@ -0,0 +1,171 @@ +package info.nightscout.utils; + +import android.content.Intent; +import android.net.Uri; + +import org.slf4j.LoggerFactory; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import ch.qos.logback.classic.LoggerContext; + +/** + * This class provides serveral methods for log-handling (eg. sending logs as emails). + */ +public class LoggerUtils { + + private static String SUFFIX = ".log.zip"; + + /** + * Returns the directory, in which the logs are stored on the system. This is configured in the + * logback.xml file. + * + * @return + */ + public static String getLogDirectory() { + LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); + return lc.getProperty("EXT_FILES_DIR"); + } + + + /** + * returns a list of log files. The number of returned logs is given via the amount + * parameter. The log files are sorted by the name descending. + * + * @param directory + * @param amount + * @return + */ + public static List getLogfiles(String directory, int amount) { + File logDir = new File(directory); + + File[] files = logDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File file, String name) { + return name.startsWith("AndroidAPS") + && (name.endsWith(".log") + || (name.endsWith(".zip") && !name.endsWith(SUFFIX))); + } + }); + + Arrays.sort(files, new Comparator() { + public int compare(File f1, File f2) { + return f2.getName().compareTo(f1.getName()); + } + }); + + List result = Arrays.asList(files); + int toIndex = amount++; + + + if (toIndex > result.size()) { + toIndex = result.size(); + } + + return result.subList(0, toIndex); + } + + /** + * Zips the given files in a zipfile which is stored in the given directory using the givven + * name. + * + * @param name + * @param directory + * @param files + * @return + */ + public static File zipLogs(String name, String directory, List files) { + File zip = new File(directory, name); + + try { + zip(zip, files); + } catch (IOException e) { + System.out.print("REmomve this one sooner or later...."); + } + + return zip; + } + + /** + * construct the name of zip file which is used to export logs. + * + * The name is constructed using the following scheme: + * AndroidAPS_LOG_ + Long Time + .log.zip + * + * @return + */ + public static String constructName() { + return "AndroidAPS_LOG_" + String.valueOf(new Date().getTime()) + SUFFIX; + } + + /** + * This method stores all given files inside the given zipFile. + * + * @param zipFile + * @param files + * @throws IOException + */ + public static void zip(File zipFile, List files) throws IOException { + final int BUFFER_SIZE = 2048; + + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + + for (File file : files) { + byte data[] = new byte[BUFFER_SIZE]; + + try(FileInputStream fileInputStream = new FileInputStream( file )) { + + try(BufferedInputStream origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE)) { + ZipEntry entry = new ZipEntry(file.getName()); + + out.putNextEntry(entry); + int count; + while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) { + out.write(data, 0, count); + } + + } + } + } + + out.close(); + } + + /** + * send a mail with the given file to the recipients with the given subject. + * + * the returned intent should be used to really send the mail using + * + * startActivity(Intent.createChooser(emailIntent , "Send email...")); + * + * @param file + * @param recipient + * @param subject + * @return + */ + public static Intent sendMail(File file, String recipient, String subject) { + Intent emailIntent = new Intent(Intent.ACTION_SEND); + + emailIntent .setType("vnd.android.cursor.dir/email"); + emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient}); + emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + + Uri path = Uri.fromFile(file); + emailIntent .putExtra(Intent.EXTRA_STREAM, path); + + return emailIntent; + } + +} diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 09bd20a631..9cbaa378cd 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -34,6 +34,10 @@ android:id="@+id/nav_show_logcat" app:showAsAction="never" android:title="@string/nav_show_logcat" /> + Copy To Clipboard Copied to clipboard Show log + Export Logs Calibration Send calibration %.1f to xDrip? xDrip+ not installed diff --git a/app/src/test/java/info/nightscout/MainAppTest.java b/app/src/test/java/info/nightscout/MainAppTest.java index 7bb58797be..569d5ded21 100644 --- a/app/src/test/java/info/nightscout/MainAppTest.java +++ b/app/src/test/java/info/nightscout/MainAppTest.java @@ -12,6 +12,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; +import info.nightscout.utils.LoggerUtils; /** @@ -127,7 +128,7 @@ public class MainAppTest { @Test public void getLogDirectoryTest() { // logger not initialized in Roboelectric - Assert.assertNull(mainApp.getLogDirectory()); + Assert.assertNull(LoggerUtils.getLogDirectory()); } } diff --git a/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java b/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java new file mode 100644 index 0000000000..b999c804b7 --- /dev/null +++ b/app/src/test/java/info/nightscout/utils/LoggerUtilsTest.java @@ -0,0 +1,40 @@ +package info.nightscout.utils; + +import org.junit.Test; + +import java.io.File; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class LoggerUtilsTest { + + @Test + public void getLogfilesTest() { + String logDirectory = "src/test/res/logger"; + + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + assertEquals(2, logs.size()); + assertEquals("AndroidAPS.log", logs.get(0).getName()); + assertEquals("AndroidAPS.2018-01-03_01-01-00.1.zip", logs.get(1).getName()); + + logs = LoggerUtils.getLogfiles(logDirectory, 10); + assertEquals(4, logs.size()); + } + + + @Test + public void zipLogsTest() { + String logDirectory = "src/test/res/logger"; + List logs = LoggerUtils.getLogfiles(logDirectory, 2); + + String name = "AndroidAPS.log.zip"; + + File zipFile = LoggerUtils.zipLogs(name, "build", logs); + + assertTrue(zipFile.exists()); + assertTrue(zipFile.isFile()); + } + +} diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-01_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-02_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip b/app/src/test/res/logger/AndroidAPS.2018-01-03_01-01-00.1.zip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/test/res/logger/AndroidAPS.log b/app/src/test/res/logger/AndroidAPS.log new file mode 100644 index 0000000000..e69de29bb2