From 95766b044fdd92a9db7bc3432f5bd442b6450bfe Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 14 Dec 2020 22:48:32 -0600 Subject: [PATCH] First attempt at finding duplicate files. For now, and possible ever, this process will be a 'best effort' approach, so there will be false positives but this will most likely remain the case for the life of this program. --- .vs/DataOrganizer/v16/.suo | Bin 149504 -> 151040 bytes DataOrganizer/FileManager.Designer.cs | 52 +++++++++++++++++++++++ DataOrganizer/FileManager.cs | 58 +++++++++++++++++++++++--- DataOrganizer/FileManager.resx | 6 --- DataOrganizer/Snapshot.cs | 34 ++++++++++++++- 5 files changed, 137 insertions(+), 13 deletions(-) diff --git a/.vs/DataOrganizer/v16/.suo b/.vs/DataOrganizer/v16/.suo index 8747cd48c2d11dafbc4d353b8acea7dfc1c3b304..2709873198d9ab3afc6cab9f388fc3b67bd3f317 100644 GIT binary patch delta 3989 zcmZpez}YZ|bAo{;69W_oFfi~kFff4l|Nj5~4-#c&U|^79U|?WnWMI(RK9P$lpK)S= z#Uv&lM*GQ%O!Axpt}Mp0FI{6aom|RP&v<*YU|;~r$wQ3ICMo(v2OcQ`=?L%aeq1H=WH3u1!;2}G+v?T}z# zV31*8VBm-HSs54@xEUB2#GrhTH{}=^7!(*GJ_6~Lgv#+TFfgb>-K@sIz`)MH5DgAL zkoQ3fVOSO9{r~^}OEWMqa4|42h%hiP7()#Ksew5T#AaYbI2;rpATbbTVw`-ABaQ{c z+-$%Z!N{?gfq`KKD9|TxNlX@z65!atz`y|V-sA&GB9pIhnec)*Abga8f#KNXKyKm9 z8r%tFYUK4{Wwf7MDpb#CH~FhjJ)`a9QsM4NLM5nzn@ffNGcvB8Tq^3%gPe#a3-YN< z{vxBZSwUh6BM&GDKyd={3rL0)6yYM9e+pOQ)~jp40@5~FLrMYU*~t-7Jt9^N3=Gx` z3=B3U=QRcf22j>wm@FtIJXt_Wgv9We ztRj79lFs4D&di3Jzv%EVZjw37h%I;w&rd$=Y{bIIz>qrmr;+z$7YUoq4Yn?fJfOq~ z%Be6HP5xpRzyrz(AXmWz8HFd8+ShZMFfcGQt!H3h02M#hjFT-K4{(6WCQ!soa&zHv zf#x!(HjT*@Zl`$}EEyOWKyeBcRheAk9>U>>6iqyB3=9mrAeozCkr&e>IcE~%k_Q}@ zP!l#E2ykGW+#F>#{X;V&%XIlZM$XAD(HfJpBSL8#nUlX*o`*z))pwQzV(m zB~Af6qR_$y7NU%nlfOCza|olTb8cYdocz`I9LOP?zxeSmP6|2~1)@ zBshS_j)8#zR%U{dvGf`S1_lmjK&GUoC6?xt#Fyk2m^hm{Pv%egYt8;f?b)t9b5{nn z>NuUU^oy&%tx(3DukBQ~b|v#GHnlG@MLJFk+tjriOZ8+g*lIf!oNrwm(N%lIrd4OM zb*kayiqwutc1K7_b+TTtR0k~&n4v`}C^7R-F7yzeSRleE2dYr?8FfJ^GoNv@K-dSy zi3KK9OqA1;W;1$h_K3N|I9bI>p1Kh;!xT_Kl|WBM*#My1IK zO?yB*iODrLWF|j&-!(a?%W87pf-{p9F0f5LcS>x#5+mb1rpZFRCet-S7)3UFbnRfC zoOCp3bI_%AjFXinbWGnR&8W0_RbLqEWTA&;o6Bx=F)o_LG?}TtWOCg@uFZ81niwZH zP4wC9^UADw@`Q%E=?-~}M<%fBBgT#Rh1_p)*1_lNfuqoT;H!~KnOpj}0FW!RW>;1~-C%fdSNn0yU*v zAa-rjV9I5gzPFvxXZw~uMt{a>lNcSRGrBST1GORs673^ zWX6W+Hmpoq(_c+x6x%kP@c`qpX^f1MYckWetIcGb#kl>zY{mx0 z$iy~%#au>-?Fa0b8ki<4W#oa}5j1_02;-#fleic^B!NR4l*6}sFfr|5oV-a>XR@rO z$aDtrlrKTqmknA} zf!LtdAUh)i0|z4m11BQ`gT!=IE+&0PF-8UkacDzQl97Qyijjdq2C7Y#5t4D`86lCb z$jHE;#K^#)%*eo?!pOh?YVUwcyllqFicAvI59Bk7fQju61&jySxl-YYW&8OG##%DEn*T_}k#ACv$=n2bc& z!^J2tiFaP}X5$V8E6LmrZA6oO~e4nz3|peU#N?`zTXIa~+Es zx5S*{)Xb{XqL_f9{ItxRR8T__)C2^zuO=HtNlJ4wCNUU5Ky8hIjsZkV1*iuy`9O4s zqRnh6*B0w2pGCqmSGAR9<(_QM+VrKBKh*cn6Q))NB?E@Zj-0|GAoF)i8ra3DAO-e? b>5L!9$`_LmsUA-nr*2XhWPvw%f~Elgi_mCs delta 3812 zcmZpe!`U!_bAo{;0}Kc-Fz_%iFfcJNF#P-f|365Wk%581fPsNQnSp^pYqBG!^u~f7 z#z{;*jJA^%ndCVOt{QKeaQ+&j=j2kRdd4-AzcT%2w4eNySvgRZfq~)w|Ns9b7#JAz zplm({1_l-e1_o{h1_n{6m^T9hgAfA)!&wFf24+Tx9!01eNIx%>{cmET^yCFBES4a_ zzaZlO|NkJTgP7V-MWzf43?Mlj1_lOQsPowv7#KJ~;u8~v83jOIm{?%K>BYdnu#JI% zL29!ut2`srHx4KN&u%?`jnNR{8&i7*28KHz{ZK1F)^UN112O*p{|^c%5K{q3UUsr0 zr*ORrR0QNZSw;p1c}4~XNvIer0|SEylq~}dZcs?bF)%QQGcYiyL2Xcis?mVb>`JCM#r=6;0RnRL7lreaotX_;K@pL(`KM?#F3)g- zJp)RU3=EV1Yr67SGcYi~q8DToFeq&Psm#uXC7Ax|9^+*+WME(br8StA&0q9*7$?c7 zP$TdR&+{^ZatO$55C(aUbvFY8L)PS`PWSHdP%**J+z`)=PO6mXq{|8yQxx}M~agvq`4Fh`e7svD1!qVwHBbFfGV8j&! zn@fxX70jk*vTt*~0t)8z_k} zF;4#H>B`HX&%nR{Dh@#gfHY1n@e1IPg@zAIka5N2uU^3%AT9_))Ok0sf}$^b@=xQ_ zVEc)56pt^=Q49C#9)uRN(Z47?F)tIu3n-dq$<(pgBjyex zBvO11g93E&7oYRIjG$BwONJn?PjAR!WMQnC{4@FT9#<6Md}U=$ov_B)M6r;GOcKdrZ`K%A_P`UPe$$3{-=` z6Y=rMrAdB}8q5VbPkl*(CbncS&Ao(yf#DV;eQo|fmyu~v7SrUW$v&HXo^4~@%#`@fF?#ZK~Sp|q@IC6?Et9wbKibZiOG^xFa;tAY7ietWME*hoPMyCv2VIvFQf7H zI~q(4OoE`)2vMYQ;0K7YJy)CQ2Mcp@vF-GOjf@uCm+CM@GfwMcbYx;+nCzP;KAo?a zQGpj!;yN-!oCnbi(~lQ3>T@zMSTlgQj??$|Gd4~>5aTz!ub&Yx;(1j56ERrZLW9oF1USWHsG@lZkD5!%W5l z+Yd|!>2sLH*f6;y+hOviL(8TsBr$SqU&q0CC4rfNfoXbSHlzRahHOS1SQJbLMZxq( zGZ{U$doVHWV4R$kr8j+@Gt;E)2WBxkFiuutl9+xVn^6QzYk%ErjRz|P3PAjZhRz{$wKz%^Z!he_WSq*R=dfk6V)PG)3akYZ$D z5QHXbkP&i>kTjsc$iSe;$iScsHByC8mF&a!nUf zVCtI8lr6{W$dJsC4DLTNFfdGKS75SS#?8dIZ3d$Q<8)}6%Y!GK2Bu}KOpIs&1UKEG zkMX}?%x*~oyEqj@O$$oSKGS0qnN*}fy;M;Cf>pxF48;r#44@7Y!}Qye7*(eqP-Jod E09XD)ssI20 diff --git a/DataOrganizer/FileManager.Designer.cs b/DataOrganizer/FileManager.Designer.cs index 639b5e7..8def445 100644 --- a/DataOrganizer/FileManager.Designer.cs +++ b/DataOrganizer/FileManager.Designer.cs @@ -53,6 +53,10 @@ this.SelectedFolderViewGroupTreeView = new System.Windows.Forms.TreeView(); this.ComparisionFolderViewGroupBox = new System.Windows.Forms.GroupBox(); this.ComparisionFolderViewTreeView = new System.Windows.Forms.TreeView(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); this.MainLayoutPanel.SuspendLayout(); this.MainMenuStrip.SuspendLayout(); this.DiffResultsGroupBox.SuspendLayout(); @@ -61,6 +65,7 @@ this.statusStrip1.SuspendLayout(); this.SelectedGroupFolderViewGroupBox.SuspendLayout(); this.ComparisionFolderViewGroupBox.SuspendLayout(); + this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // MainLayoutPanel @@ -78,6 +83,7 @@ this.MainLayoutPanel.Controls.Add(this.statusStrip1, 0, 4); this.MainLayoutPanel.Controls.Add(this.SelectedGroupFolderViewGroupBox, 2, 2); this.MainLayoutPanel.Controls.Add(this.ComparisionFolderViewGroupBox, 2, 3); + this.MainLayoutPanel.Controls.Add(this.groupBox1, 2, 1); this.MainLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.MainLayoutPanel.Location = new System.Drawing.Point(0, 0); this.MainLayoutPanel.Name = "MainLayoutPanel"; @@ -326,6 +332,46 @@ this.ComparisionFolderViewTreeView.Size = new System.Drawing.Size(420, 326); this.ComparisionFolderViewTreeView.TabIndex = 0; // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button2); + this.groupBox1.Controls.Add(this.button1); + this.groupBox1.Controls.Add(this.textBox1); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(877, 43); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(426, 172); + this.groupBox1.TabIndex = 12; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "groupBox1"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(29, 34); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(239, 26); + this.textBox1.TabIndex = 0; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(296, 38); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 1; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // button2 + // + this.button2.Location = new System.Drawing.Point(16, 120); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(112, 46); + this.button2.TabIndex = 2; + this.button2.Text = "button2"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click); + // // FileManager // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); @@ -346,6 +392,8 @@ this.statusStrip1.PerformLayout(); this.SelectedGroupFolderViewGroupBox.ResumeLayout(false); this.ComparisionFolderViewGroupBox.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); this.ResumeLayout(false); } @@ -377,5 +425,9 @@ private System.Windows.Forms.TreeView SelectedFolderViewGroupTreeView; private System.Windows.Forms.GroupBox ComparisionFolderViewGroupBox; private System.Windows.Forms.TreeView ComparisionFolderViewTreeView; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Button button2; } } \ No newline at end of file diff --git a/DataOrganizer/FileManager.cs b/DataOrganizer/FileManager.cs index 89e1d76..ef014e1 100644 --- a/DataOrganizer/FileManager.cs +++ b/DataOrganizer/FileManager.cs @@ -77,17 +77,47 @@ namespace DataOrganizer var db = new DB(); var p = GetProfileToCompare(); var f = GetFolderGroupToCompare(); + var renames = new List(); ComparisionSnapshot = new Snapshot(db.GetFilesForProfileByFolderGroup(p.Id, f.Id), f); var diff = ActiveSnapshot.Diff(ComparisionSnapshot); - foreach(var file in diff.NewFiles) - AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingInsert); + //foreach (var folder in ActiveSnapshot.Directories.Values) + //{ + // if (ComparisionSnapshot.Directories.ContainsKey(folder.FullPath)) + // { + // renames.AddRange(ActiveSnapshot.FindFileRenames(folder, ComparisionSnapshot.Directories[folder.FullPath])); + // } + //} - foreach (var file in diff.ModifiedFiles) - AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingUpdate); + //foreach (var rename in renames) + //{ + // DiffViewTreeView.Nodes.Add($"From: {rename.From.Name}"); + // DiffViewTreeView.Nodes.Add($"To: {rename.To.Name}"); + //} + var dupCount = 0; - foreach (var file in diff.DeletedFiles) - AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingDelete); + foreach(var folder in ActiveSnapshot.TopLevelFolders.Keys) + { + foreach(var dup in ActiveSnapshot.FindDuplicates(ActiveSnapshot.Directories[folder])) + { + var node = new TreeNode($"{dup.File.Name} ({dup.Duplicates.Count})") { ToolTipText = dup.File.FullPath }; + foreach(var d in dup.Duplicates) + { + node.Nodes.Add(new TreeNode(d.Name) { ToolTipText = d.FullPath }); + dupCount++; + } + DiffViewTreeView.Nodes.Add(node); + } + } + UpdateStatusLabel($"Found {dupCount} duplicate files."); + //foreach(var file in diff.NewFiles) + // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingInsert); + + //foreach (var file in diff.ModifiedFiles) + // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingUpdate); + + //foreach (var file in diff.DeletedFiles) + // AddFileSnapshotToDiffView(file, GetSelectedFolderGroup(), FileSnapshot.FileStatus.PendingDelete); } private void AddFileSnapshotToDiffView(FileSnapshot file, DB.FolderGroup folderGroup, FileSnapshot.FileStatus fileStatus = FileSnapshot.FileStatus.None) @@ -324,5 +354,21 @@ namespace DataOrganizer StatusLabel.Text = message; statusStrip1.Refresh(); } + + private void button1_Click(object sender, EventArgs e) + { + var form = new FolderBrowserDialog(); + + if(form.ShowDialog() == DialogResult.OK) + { + textBox1.Text = form.SelectedPath; + } + } + + private void button2_Click(object sender, EventArgs e) + { + //Compare + + } } } diff --git a/DataOrganizer/FileManager.resx b/DataOrganizer/FileManager.resx index 57b87f9..0e5bf2c 100644 --- a/DataOrganizer/FileManager.resx +++ b/DataOrganizer/FileManager.resx @@ -123,10 +123,4 @@ 205, 17 - - 17, 17 - - - 205, 17 - \ No newline at end of file diff --git a/DataOrganizer/Snapshot.cs b/DataOrganizer/Snapshot.cs index e009b0a..c3d2ae9 100644 --- a/DataOrganizer/Snapshot.cs +++ b/DataOrganizer/Snapshot.cs @@ -272,9 +272,41 @@ namespace DataOrganizer return renames; } + public List FindDuplicates(Folder topLevelFolder) + { + var duplicates = new Dictionary(); + var files = topLevelFolder.GetAllFiles(); + var fileCount = 0; + + fileCount = files.Count; + + for(var i = 0; i < fileCount; i++) + { + var file = files[i]; + + //if (!duplicates.ContainsKey(file.FullPath)) duplicates.Add(file.FullPath, new Duplicate() { File = file, Duplicates = new List() }); + + var dups = files.Where(x => x.Size == file.Size && x.FileId != file.FileId).ToList(); + var dupCount = dups.Count; + + if(dupCount > 0) + if (!duplicates.ContainsKey(file.FullPath)) duplicates.Add(file.FullPath, new Duplicate() { File = file, Duplicates = new List() }); + + for (var j = 0; j < dupCount; j++) + { + var dup = dups[j]; + files.Remove(dup); + duplicates[file.FullPath].Duplicates.Add(dup); + fileCount--; + } + } + + return duplicates.Values.ToList(); + } + public struct Duplicate { - public DB.DBFileSnapshot File; + public FileSnapshot File; public List Duplicates; } }