lantool

ein feines Tool für LANs (damals)
git clone https://git.clttr.info/lantool.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

StuffItemTree.cs (7810B)


      1 using System.Collections.Generic;
      2 using System.IO;
      3 using LanTool.Classes;
      4 using System;
      5 
      6 namespace LanTool
      7 {
      8 	internal class StuffItemTree : StuffItem
      9 	{
     10 		#region private fields
     11 
     12 		private SortedDictionary<string, List<StuffItem>> stuffItemTreeByHash = new SortedDictionary<string, List<StuffItem>>();
     13 		private SortedDictionary<string, List<StuffItem>> stuffItemTreeByName = new SortedDictionary<string, List<StuffItem>>();
     14 		private long myDisksSpaceByClones = 0;
     15 		private long myDisksCountOfClones = 0;
     16 		private long myDisksCountOfAllowedClones = 0;
     17 		private long myDisksSpaceByAllowedClones = 0;
     18 
     19 		#endregion
     20 
     21 		/// <summary>
     22 		/// Root-Item der eigenen Platten
     23 		/// </summary>
     24 		public StuffItemTree(String path, Boolean isForeign)
     25 		{
     26 			Path = path;
     27 			IsOnForeignDisk = isForeign;
     28 			IsOnline = true;
     29 		}
     30 
     31 		#region public methods
     32 
     33 		public void CreateStuffItemTreeHash()
     34 		{
     35 			stuffItemTreeByHash.Clear();
     36 			// Rücksetzen der Werte
     37 			myDisksCountOfClones = 0;
     38 			myDisksSpaceByClones = 0;
     39 			myDisksCountOfAllowedClones = 0;
     40 			myDisksSpaceByAllowedClones = 0;
     41 			// Füllen eigenen Disks
     42 			AddStuffItemToHashes( this );
     43 
     44 			if ( !IsOnForeignDisk )
     45 			{
     46 				Program.MainWindow.Log( "Dublettensuche auf eigenen Platten..." );
     47 				// Ausgabe der Ergebnisse der Dublettenprüfung
     48 				if ( myDisksCountOfClones == 0 && myDisksCountOfAllowedClones == 0 )
     49 				{
     50 					Program.MainWindow.LogHighlight( "Keine doppelten Dateien in 'Meine Platten', gut aufgeräumt!" );
     51 				}
     52 				else
     53 				{
     54 					Program.MainWindow.LogError( "Doppelte Dateien in 'Meine Platten': " + myDisksCountOfClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByClones / 104857 ) ) / 10 ).ToString() + " MB wertvoller Plattenplatz!" );
     55 					Program.MainWindow.LogWarning( "Erlaubte doppelte Dateien in 'Meine Platten': " + myDisksCountOfAllowedClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByAllowedClones / 104857 ) ) / 10 ).ToString() + " MB Plattenplatz!" );
     56 				}
     57 			}
     58 		}
     59 		
     60 		/// <summary>
     61 		/// Gibt die Dublettenliste des Items zurück (ohne das Item selbst).
     62 		/// Eine leere Liste bedeutet also, dass das Item keine Clones hat.
     63 		/// </summary>
     64 		public List<StuffItem> GetItemClones( StuffItem item )
     65 		{
     66 			List<StuffItem> clonecopy = new List<StuffItem>();
     67 
     68 			// Alle Items mit dem gleichen Hash merken
     69 			List<StuffItem> clones = GetItemsRecursive( item );
     70 
     71 			// alle Items durchgehen und das Ursprungsitem wieder raussortieren
     72 			foreach ( StuffItem si in clones )
     73 			{
     74 				if ( si != item )
     75 				{
     76 					clonecopy.Add( si );
     77 				}
     78 			}
     79 			return clonecopy;
     80 		}
     81 
     82 		/// <summary>
     83 		/// Zurückgeben, wie oft ein Item (Hash-Test) im MyDisks hängt
     84 		/// </summary>
     85 		/// <param name="item"></param>
     86 		/// <returns></returns>
     87 		public int GetRecursiveItemCount( StuffItem item )
     88 		{
     89 			return GetItemsRecursive( item ).Count;
     90 		}
     91 
     92 		/// <summary>
     93 		/// Liefert alle StuffItems, die den gleichen Hash haben wie das übergebene
     94 		/// StuffItem
     95 		/// </summary>
     96 		/// <param name="item"></param>
     97 		/// <returns></returns>
     98 		public List<StuffItem> GetItemsRecursive( StuffItem item )
     99 		{
    100 			List<StuffItem> retList = new List<StuffItem>();
    101 
    102 			// keine Dubletten bei Dateien mit Lesefehler
    103 			if ( item.HasReadError )
    104 			{
    105 				return retList;
    106 			}
    107 
    108 			// wenn die Datei in keiner Liste enthalten ist (weder Hash noch Name), dann raus
    109 			if ( !stuffItemTreeByHash.ContainsKey( item.Hash ) && !stuffItemTreeByName.ContainsKey( item.Name ) )
    110 			{
    111 				return retList;
    112 			}
    113 
    114 			// Alle Items by Hash ermitteln
    115 			if (stuffItemTreeByHash.ContainsKey( item.Hash ) )
    116 			{
    117 				retList.AddRange( stuffItemTreeByHash[ item.Hash ] );
    118 			}
    119 
    120 			// restliche Prüfung nur, wenn die Namensprüfung angeschalten ist und die Datei auch enthalten ist
    121 			if ( Program.MainWindow.m_Config.IsTreatEqualNames && stuffItemTreeByName.ContainsKey( item.Name ) )
    122 			{
    123 				// wenn die Datei überhaupt vorhanden ist, dann checken ob
    124 				foreach ( StuffItem si in stuffItemTreeByName[ item.Name ] )
    125 				{
    126 					if ( !retList.Contains( si ) )
    127 					{
    128 						retList.Add( si );
    129 					}
    130 				}
    131 			}
    132 
    133 			return retList;
    134 		}
    135 
    136 		#endregion
    137 
    138 		#region Private methods
    139 
    140 		private void AddStuffItemToHashes( StuffItem si )
    141 		{
    142 			// nur Dateien verarbeiten
    143 			if ( si.IsFile )
    144 			{
    145 				// Name-Cache bearbeiten
    146 				if ( !stuffItemTreeByName.ContainsKey( si.Name ) )
    147 				{
    148 					stuffItemTreeByName[ si.Name ] = new List<StuffItem>();
    149 					stuffItemTreeByName[ si.Name ].Add( si );
    150 				}
    151 				else
    152 				{
    153 					stuffItemTreeByName[ si.Name ].Add( si );
    154 				}
    155 
    156 				// Hash-Cache bearbeiten
    157 				if ( !stuffItemTreeByHash.ContainsKey( si.Hash ) )
    158 				{
    159 					stuffItemTreeByHash[ si.Hash ] = new List<StuffItem>();
    160 					stuffItemTreeByHash[ si.Hash ].Add( si );
    161 				}
    162 				else
    163 				{
    164 					stuffItemTreeByHash[ si.Hash ].Add( si );
    165 					if ( si.IsIgnored )
    166 					{
    167 						try
    168 						{
    169 							myDisksSpaceByAllowedClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 );
    170 						}
    171 						catch
    172 						{
    173 						}
    174 						myDisksCountOfAllowedClones++;
    175 					}
    176 					else
    177 					{
    178 						try
    179 						{
    180 							myDisksSpaceByClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 );
    181 						}
    182 						catch
    183 						{
    184 						}
    185 						myDisksCountOfClones++;
    186 					}
    187 				}
    188 			}
    189 			else
    190 			{
    191 				// Verzeichnis -> alle Childs durchgehen
    192 				foreach ( StuffItem csi in si.ChildItems )
    193 				{
    194 					AddStuffItemToHashes( csi );
    195 				}
    196 			}
    197 		}
    198 
    199 		internal void RemoveStuffItemFromHashes( StuffItem si )
    200 		{
    201 			// StuffItem aus der Liste mit Hashes entfernen
    202 			stuffItemTreeByHash[ si.Hash ].Remove( si );
    203 
    204 			// StuffItem aus der Namensliste entfernen
    205 			stuffItemTreeByName[ si.Name ].Remove( si );
    206 		}
    207 
    208 		#endregion
    209 
    210 		#region FileSystemCache für Offline-Betrieb
    211 
    212 		private Dictionary<string, List<string>> offlineDirs = new Dictionary<string, List<string>>();
    213 		private Dictionary<string, List<string>> offlineFiles = new Dictionary<string, List<string>>();
    214 
    215 		public override Dictionary<string, List<string>> OfflineDirs
    216 		{
    217 			get
    218 			{
    219 				return offlineDirs;
    220 			}
    221 		}
    222 
    223 		public override Dictionary<string, List<string>> OfflineFiles
    224 		{
    225 			get
    226 			{
    227 				return offlineFiles;
    228 			}
    229 		}
    230 
    231 		/// <summary>
    232 		/// Offline Cache in eine Datei schreiben
    233 		/// </summary>
    234 		/// <param name="filename"></param>
    235 		public void SaveOfflineCacheToFile( string filename )
    236 		{
    237 			using ( StreamWriter sw = File.CreateText( filename ) )
    238 			{
    239 				foreach ( string sa in offlineDirs.Keys )
    240 				{
    241 					foreach ( string sb in offlineDirs[ sa ] )
    242 					{
    243 						sw.WriteLine( "D|" + sa + "|" + sb );
    244 					}
    245 				}
    246 				foreach ( string sa in offlineFiles.Keys )
    247 				{
    248 					foreach ( string sb in offlineFiles[ sa ] )
    249 					{
    250 						sw.WriteLine( "F|" + sa + "|" + sb );
    251 					}
    252 				}
    253 			}
    254 
    255 			Program.MainWindow.Log( "Offline-Verzeichnis wurde nach " + filename + " geschrieben" );
    256 		}
    257 
    258 
    259 		/// <summary>
    260 		/// Offline-Cache aus einer Datei lesen
    261 		/// </summary>
    262 		/// <param name="filename"></param>
    263 		public void LoadOfflineCacheFromFile( string filename )
    264 		{
    265 			using ( StreamReader sr = File.OpenText( filename ) )
    266 			{
    267 				string line;
    268 				while ( ( line = sr.ReadLine() ) != null )
    269 				{
    270 					string[] zeile = line.Split( '|' );
    271 					if ( zeile[ 0 ] == "F" )
    272 					{
    273 						if ( !OfflineFiles.ContainsKey( zeile[ 1 ] ) )
    274 						{
    275 							OfflineFiles[ zeile[ 1 ] ] = new List<string>();
    276 						}
    277 						OfflineFiles[ zeile[ 1 ] ].Add( zeile[ 2 ] );
    278 					}
    279 					else
    280 					{
    281 						if ( !offlineDirs.ContainsKey( zeile[ 1 ] ) )
    282 						{
    283 							offlineDirs[ zeile[ 1 ] ] = new List<string>();
    284 						}
    285 						offlineDirs[ zeile[ 1 ] ].Add( zeile[ 2 ] );
    286 					}
    287 				}
    288 			}
    289 			IsOnline = false;
    290 		}
    291 
    292 		/// <summary>
    293 		/// Simulation des Filesystems abschalten und zurücksetzen
    294 		/// </summary>
    295 		public void ResetOfflineCaches()
    296 		{
    297 			offlineDirs.Clear();
    298 			offlineFiles.Clear();
    299 		}
    300 
    301 		#endregion
    302 	}
    303 }