bykovme/nswallet

View on GitHub
src/NSWallet/Droid/Interfaces/ExportService.cs

Summary

Maintainability
F
3 days
Test Coverage
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Android.App;
using Android.Graphics;
using Android.Graphics.Pdf;
using Android.Util;
using NSWallet.Droid;
using NSWallet.iOS.Interfaces;
using NSWallet.Shared;
using NSWallet.Shared.Helpers.Logs.AppLog;
using Xamarin.Forms;

[assembly: Dependency(typeof(ExportService))]
namespace NSWallet.Droid
{
    public class ExportService : IExport
    {
        static List<PDFItemModel> ExportedItems { get; set; }

        static string path;

        static void CleanCache()
        {
            var backupPath = PlatformSpecific.GetBackupPath();
            var directories = Directory.EnumerateDirectories(backupPath);
            foreach(var directory in directories) {
                if (directory.Contains("cache.")) {
                    PlatformSpecific.RemoveDirectoryWithContents(directory);
                }
            }
        }

        static void EnumerateItems(string id, bool recursive = false)
        {
            try {
                foreach (var item in BL.GetListByParentID(id, true)) {
                    if (!recursive)
                        path = "/";

                    if (!item.Folder) {

                        ExportedItems.Add(new PDFItemModel {
                            Name = item.Name,
                            Image = item.Icon,
                            ItemType = ExportItemTypes.Item,
                            Path = path
                        });

                        path += item.Name + "/";

                        if (item.Fields != null) {
                            foreach (var field in item.Fields) {
                                string fieldType = null;
                                if (TR.Tr(field.FieldType) == field.FieldType) {
                                    fieldType = field.Label;
                                } else {
                                    fieldType = TR.Tr(field.FieldType);
                                }
                                ExportedItems.Add(new PDFItemModel {
                                    Name = fieldType + ": " + field.HumanReadableValue,
                                    Image = field.Icon,
                                    ItemType = ExportItemTypes.Field,
                                    Path = path
                                });
                            }
                        }
                    } else {
                        ExportedItems.Add(new PDFItemModel {
                            Name = item.Name,
                            Image = item.Icon,
                            ItemType = ExportItemTypes.Folder,
                            Path = path
                        });

                        path += item.Name + "/";

                        EnumerateItems(item.ItemID, true);
                    }
                }

            } catch (Exception ex) {
                log(ex.Message, nameof(EnumerateItems));
            }
        }

        public void GenerateTXT()
        {
            CleanCache();

            // Get NSWItems
            ExportedItems = new List<PDFItemModel>();
            EnumerateItems(GConsts.ROOTID);

            string fileName = "nswallet" + DateTime.Now.ToString("-dd-MM-yyyy-hh-mm-ss") + ".txt";
            var tempFolder = PlatformSpecific.GetBackupPath() + "/cache" + "." + Common.GenerateUniqueString(8);
            PlatformSpecific.CreateFolder(tempFolder);
            string exportPath = tempFolder + "/" + fileName;
            bool isField = false;
            int count = 0;

            using (StreamWriter sw = new StreamWriter(exportPath)) {
                foreach (var item in ExportedItems) {
                    if (item.ItemType == ExportItemTypes.Field) {
                        if (!isField) {
                            if(count > 0) sw.WriteLine();
                            sw.WriteLine(String.Format("[{0}]", item.Path));
                            sw.WriteLine(item.Name);
                        } else {
                            sw.WriteLine(item.Name);
                        }
                        isField = true;
                        count++;
                    } else {
                        isField = false;
                    }
                }
            }

            var sharing = new SharingDroid();
            sharing.ShareFile(exportPath, TR.Tr("app_name"), "text/*", TR.Tr("export_data"), null);
        }

        public void GeneratePDF()
        {
            CleanCache();

            // Get NSWItems
            ExportedItems = new List<PDFItemModel>();
            EnumerateItems(GConsts.ROOTID);

            // create PDF
            var PDFDoc = new PdfDocument();

            // create a page description
            DisplayMetrics displayMetrics = new DisplayMetrics();
            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(2000, 150 * 20, 0).Create();
            PdfDocument.Page page = null;

            int xPosMatrix = 20, yPosMatrix = 10;
            int xPosText = 170, yPosText = 99;
            int paintTextSize = 50;
            int counter = 1;

            foreach (var item in ExportedItems) {

                if (counter == 1) {
                    // start page
                    page = PDFDoc.StartPage(pageInfo);
                }

                if (item.ItemType == ExportItemTypes.Folder) {
                    yPosMatrix += 20;
                }

                if (item.ItemType == ExportItemTypes.Field) {
                    xPosText += 100;
                    xPosMatrix += 100;
                }

                var imageStream = NSWRes.GetImage(item.Image);
                if (imageStream == null) {
                    if (item.Image != null) {
                        var customIcons = BL.GetIcons();
                        var customIcon = customIcons.Find(x => item.Image.Contains(x.IconID));
                        imageStream = customIcon != null ?
                            new MemoryStream(customIcon.Icon) :
                            NSWRes.GetImage(GConsts.DEFAULT_ITEM_ICON);
                    } else {
                        imageStream = NSWRes.GetImage(GConsts.DEFAULT_ITEM_ICON);
                    }
                }

                var imageBytesArray = GetBytesFromStream(imageStream);
                var options = new BitmapFactory.Options();
                options.InMutable = true;
                var bitmap = BitmapFactory.DecodeByteArray(imageBytesArray, 0, imageBytesArray.Length, options);

                var matrix = new Matrix();
                matrix.PostTranslate(xPosMatrix, yPosMatrix);

                // add image to the page
                page.Canvas.DrawBitmap(bitmap, matrix, null);

                Paint paint = new Paint();
                paint.TextSize = paintTextSize;
                if (item.ItemType == ExportItemTypes.Field) {

                    var saveXPosMatrix = xPosMatrix;
                    var saveXPosText = xPosText;

                    var strings = WrapString(item.Name, 77);
                    int wordCounter = 1;
                    foreach (var str in strings) {
                        page.Canvas.DrawText(str, xPosText, yPosText, paint);

                        if (wordCounter != strings.Length) {

                            if (counter == 20) {
                                PDFDoc.FinishPage(page);
                                xPosMatrix = 20;
                                yPosMatrix = 10;
                                xPosText = 270;
                                yPosText = 99;
                                counter = 1;
                                page = PDFDoc.StartPage(pageInfo);
                            } else {
                                counter++;
                                yPosMatrix += 10 + 128 + 10 - 49;
                                yPosText += 99;
                            }
                        }
                        wordCounter++;
                    }
                    xPosMatrix = saveXPosMatrix;
                    xPosText = saveXPosText;
                } else {
                    page.Canvas.DrawText(item.Name, xPosText, yPosText, paint);
                }

                yPosMatrix += 10 + 128 + 10;
                yPosText += 99 + 49;

                if (item.ItemType == ExportItemTypes.Folder) {
                    yPosMatrix -= 20;
                }

                if (item.ItemType == ExportItemTypes.Field) {
                    xPosText -= 100;
                    xPosMatrix -= 100;
                }

                if (counter == 20) {
                    PDFDoc.FinishPage(page);
                    xPosMatrix = 20;
                    yPosMatrix = 10;
                    xPosText = 170;
                    yPosText = 99;
                    paintTextSize = 50;
                    counter = 1;
                } else {
                    counter++;
                }
            }

            if (page.Canvas != null)
                PDFDoc.FinishPage(page);

            // save PDF
            string fileName = "nswallet" + DateTime.Now.ToString("-dd-MM-yyyy-hh-mm-ss") + ".pdf";
            var tempFolder = PlatformSpecific.GetBackupPath() + "/cache" + "." + Common.GenerateUniqueString(8);
            PlatformSpecific.CreateFolder(tempFolder);
            string exportPath = tempFolder + "/" + fileName;
            FileStream fileStream = new FileStream(exportPath, FileMode.CreateNew);

            PDFDoc.WriteTo(fileStream);
            fileStream.Flush();

            // close PDF
            PDFDoc.Close();

            var sharing = new SharingDroid();
            sharing.ShareFile(exportPath, TR.Tr("app_name"), "application/pdf", TR.Tr("export_data"), null);
        }

        public static byte[] GetBytesFromStream(Stream input)
        {
            using (MemoryStream ms = new MemoryStream()) {
                input.CopyTo(ms);
                return ms.ToArray();
            }
        }

        public static string[] WrapString(string text, int max)
        {
            var charCount = 0;
            var lines = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            return lines.GroupBy(w => (charCount += (((charCount % max) + w.Length + 1 >= max)
                            ? max - (charCount % max) : 0) + w.Length + 1) / max)
                        .Select(g => string.Join(" ", g.ToArray()))
                        .ToArray();
        }

        static void log(string message, string method = null)
        {
            AppLogs.Log(message, method, nameof(ExportService));
        }
    }
}