aboutsummaryrefslogtreecommitdiff
path: root/src/Commands/PreviewCommand.cs
blob: aea4afce90c705a378e949f739645d87a4b627e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Extensions.CommandLineUtils;

namespace iPhotoExtractor.Commands
{
    public class PreviewCommand : ICommand
    {
        private const char TEE = '\u251c';
        private const char ELBOW = '\u2514';
        private const char V_BAR = '\u2502';
        private const char H_BAR = '\u2500';

        public static void Configure(CommandLineApplication command)
        {
            command.HelpOption("-h|--help");
            command.Description = "Display the directory structure that would result from " +
                "running 'iPhotoExtractor extract'.";

            var libPathArgument = command.Argument(
                "library_dir",
                "Path to the iPhoto library directory.");

            var outputDirArgument = command.Argument(
                "[output_dir]",
                "Path to the directory where extracted photos will be copied.");

            command.OnExecute(() =>
            {
                (new PreviewCommand(libPathArgument.Value, outputDirArgument.Value)).Run();
                return 0;
            });
        }

        private readonly string _libraryDir;
        private readonly string _outputDir;

        public PreviewCommand(string libraryDir, string outputDir)
        {
            _libraryDir = libraryDir;
            _outputDir = outputDir;
        }

        public void Run()
        {
            var libraryDir = String.IsNullOrWhiteSpace(_libraryDir) ?
                Directory.GetCurrentDirectory() :
                _libraryDir;

            var outputDir = String.IsNullOrWhiteSpace(_outputDir) ?
                Directory.GetCurrentDirectory() :
                _outputDir;

            var dbPath = Path.Combine(libraryDir, "iPhotoMain.db");

            if (!File.Exists(dbPath))
            {
                Console.WriteLine($"File '{dbPath}' not found.");
                return;
            }

            var photoStore = new PhotoStore(dbPath);
            List<Photo> photos = photoStore.GetAllPhotos();

            Dictionary<string, List<Photo>> albums = photos
                .GroupBy(p => p.AlbumName)
                .ToDictionary(g => g.Key, g => g.ToList());

            Console.WriteLine(_outputDir);
            string album;

            for (int i = 0; i < albums.Keys.Count - 1; i++)
            {
                album = albums.Keys.ElementAt(i);
                DrawAlbumTree(album, albums[album], false);
            }

            album = albums.Keys.Last();
            DrawAlbumTree(album, albums[album], true);
        }

        private void DrawAlbumTree(string albumName, List<Photo> photos, bool isLastChild)
        {
            var modified = photos
                .Where(p => p.HasModifiedVersion() && p.HasOriginalVersion())
                .ToList();

            var hasModified = modified.Any();
            string prefix = isLastChild ? "    " : $"{V_BAR}   ";

            Console.WriteLine($"{GetCurrLevelTreeString(isLastChild)}{albumName}");
            DrawPhotos(photos, prefix, hasModified);

            if (!hasModified)
                return;

            Console.WriteLine($"{prefix}{GetCurrLevelTreeString(true)}Originals");
            DrawPhotos(modified, prefix + "    ", false);
        }

        private void DrawPhotos(List<Photo> photos, string prefix, bool hasModified)
        {
            for (int i = 0; i < photos.Count; i++)
            {
                var photo = photos.ElementAt(i);
                var isLastChild = i == photos.Count - 1 && !hasModified;

                List<string> paths = new List<string>();

                if (hasModified)
                    paths.AddRange(photo.GetUniquePaths(PhotoPathType.Modified));

                if (!paths.Any())
                    paths.AddRange(photo.GetUniquePaths(PhotoPathType.Original));

                if (!paths.Any())
                    paths.Add("");

                for (int j = 0; j < paths.Count; j++)
                {
                    var path = paths.ElementAt(j);

                    if (j < paths.Count - 1)
                        DrawPhoto(path, prefix, false);
                    else
                        DrawPhoto(path, prefix, isLastChild);
                }
            }
        }

        private void DrawPhoto(string relativePath, string prefix, bool isLastChild)
        {
            string fileName = Path.GetFileName(relativePath);
            string currLevel = GetCurrLevelTreeString(isLastChild);

            Console.WriteLine($"{prefix}{currLevel}{fileName} ({relativePath})");
        }

        private string GetCurrLevelTreeString(bool isLastChild)
        {
            if (isLastChild)
                return $"{ELBOW}{H_BAR}{H_BAR} ";
            else
                return $"{TEE}{H_BAR}{H_BAR} ";
        }
    }
}