Beispiel #1
0
		public async Task<QuerySummary> QueryAsync(string sourcePath, bool recursive, QueryType queries, params MetaType[] types)
		{
			if (String.IsNullOrEmpty(sourcePath))
				throw new ArgumentNullException(nameof(sourcePath));
			if (!Directory.Exists(sourcePath))
				throw new DirectoryNotFoundException(sourcePath);
			if (queries == QueryType.None)
				throw new ArgumentException("No queries given.");

			Dictionary<string, IEnumerable<Tuple<string, QueryType>>> duplicates = new Dictionary<string, IEnumerable<Tuple<string, QueryType>>>();
			Dictionary<string, string> md5sums = new Dictionary<string, string>();
			Dictionary<string, string> sha1sums = new Dictionary<string, string>();
			IEnumerable<MetaData> data = await GetMetaData(sourcePath, recursive, types);
			foreach (MetaData item in data.Where(x => x.Type != MetaType.Directory && x.Type != MetaType.File))
			{
				List<Tuple<string, QueryType>> matches = new List<Tuple<string, QueryType>>();
				foreach (MetaData other in data.Where(x => x.Type != MetaType.Directory && x.Type != MetaType.File && !x.Equals(item)))
				{
					QueryType match = QueryType.None;

					bool equalFilename = Path.GetFileName(item.Path).Equals(Path.GetFileName(other.Path), StringComparison.Ordinal /* TODO: which type? */);
					if (queries.HasFlag(QueryType.EqualFileName) && equalFilename)
							match |= QueryType.EqualFileName;

					if (queries.HasFlag(QueryType.EqualFileNameDifferentFileSize) && equalFilename)
					{
							if (item.Data[MetaKey.Size] != other.Data[MetaKey.Size])
								match |= QueryType.EqualFileNameDifferentFileSize;
					}

					if (queries.HasFlag(QueryType.EqualChecksumMD5) || queries.HasFlag(QueryType.EqualFileNameDifferentChecksumMD5))
					{
							string md5item;
							if (!md5sums.TryGetValue(item.Path, out md5item))
							{
								md5item = GetMD5(item.Path);
								md5sums[item.Path] = md5item;
							}

							string md5other;
							if (!md5sums.TryGetValue(other.Path, out md5other))
							{
								md5other = GetMD5(other.Path);
								md5sums[other.Path] = md5other;
							}

						bool md5match = md5item.Equals(md5other, StringComparison.Ordinal);
						if (queries.HasFlag(QueryType.EqualChecksumMD5) && md5match)
							match |= QueryType.EqualChecksumMD5;
						if (queries.HasFlag(QueryType.EqualFileNameDifferentChecksumMD5) && equalFilename && !md5match)
							match |= QueryType.EqualFileNameDifferentChecksumMD5;
					}

					if (queries.HasFlag(QueryType.EqualChecksumSHA1) || queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA1))
					{
						string sha1item;
						if (!sha1sums.TryGetValue(item.Path, out sha1item))
						{
							sha1item = GetSHA1(item.Path);
							sha1sums[item.Path] = sha1item;
						}

						string sha1other;
						if (!sha1sums.TryGetValue(other.Path, out sha1other))
						{
							sha1other = GetSHA1(other.Path);
							sha1sums[other.Path] = sha1other;
						}

						bool sha1match = sha1item.Equals(sha1other, StringComparison.Ordinal);
						if (queries.HasFlag(QueryType.EqualChecksumSHA1) && sha1match)
							match |= QueryType.EqualChecksumSHA1;
						if (queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA1) && equalFilename && !sha1match)
							match |= QueryType.EqualFileNameDifferentChecksumSHA1;
					}

					if ((queries.HasFlag(QueryType.LowResolution) || queries.HasFlag(QueryType.EqualFileNameDifferentResolution)) && item.Data.ContainsKey(MetaKey.Resolution))
					{
						//const int limit = 960 * 1280;
						const int resolutionLimit = 1024 * 768;

						int resolutionItem = (int)item.Data[MetaKey.Width] * (int)item.Data[MetaKey.Height];
						if (resolutionItem <= resolutionLimit)
							match |= QueryType.LowResolution;

						if (queries.HasFlag(QueryType.EqualFileNameDifferentResolution) && other.Data.ContainsKey(MetaKey.Resolution) && equalFilename)
						{
							int resolutionOther = (int)other.Data[MetaKey.Width] * (int)other.Data[MetaKey.Height];
							if (resolutionItem != resolutionOther)
								match |= QueryType.EqualFileNameDifferentResolution;
						}
					}

					if (match != QueryType.None)
						matches.Add(Tuple.Create(other.Path, match));
				}

				if (matches.Count > 0)
					duplicates[item.Path] = matches;
			}

			QuerySummary result = new QuerySummary();
			result.duplicates = duplicates;
			return result;
		}
        public async Task <QuerySummary> QueryAsync(string sourcePath, bool recursive, QueryType queries, params MetaType[] types)
        {
            if (String.IsNullOrEmpty(sourcePath))
            {
                throw new ArgumentNullException(nameof(sourcePath));
            }
            if (!Directory.Exists(sourcePath))
            {
                throw new DirectoryNotFoundException(sourcePath);
            }
            if (queries == QueryType.None)
            {
                throw new ArgumentException("No queries given.");
            }

            Dictionary <string, IEnumerable <Tuple <string, QueryType> > > allMatches = new Dictionary <string, IEnumerable <Tuple <string, QueryType> > >();
            Dictionary <string, string> md5sums    = new Dictionary <string, string>();
            Dictionary <string, string> sha1sums   = new Dictionary <string, string>();
            Dictionary <string, string> sha256sums = new Dictionary <string, string>();
            IEnumerable <MetaData>      data       = await GetMetaData(sourcePath, recursive, types);

            foreach (MetaData item in data.Where(x => x.Type != MetaType.Directory && x.Type != MetaType.File))
            {
                List <Tuple <string, QueryType> > matches = new List <Tuple <string, QueryType> >();
                foreach (MetaData other in data.Where(x => x.Type != MetaType.Directory && x.Type != MetaType.File && !x.Equals(item)))
                {
                    QueryType match = QueryType.None;

                    bool equalFilename = Path.GetFileName(item.Path).Equals(Path.GetFileName(other.Path), StringComparison.Ordinal);
                    if (queries.HasFlag(QueryType.EqualFileName) && equalFilename)
                    {
                        match |= QueryType.EqualFileName;
                    }

                    if (queries.HasFlag(QueryType.EqualFileNameDifferentFileSize) && equalFilename)
                    {
                        if (RequireMetaKey(MetaKey.Size, item, other))
                        {
                            if (item.Data[MetaKey.Size] != other.Data[MetaKey.Size])
                            {
                                match |= QueryType.EqualFileNameDifferentFileSize;
                            }
                        }
                    }

                    if (queries.HasFlag(QueryType.EqualChecksumMD5) || queries.HasFlag(QueryType.EqualFileNameDifferentChecksumMD5))
                    {
                        string md5item;
                        if (!md5sums.TryGetValue(item.Path, out md5item))
                        {
                            using (FileStream fileStream = File.OpenRead(item.Path))
                                md5item = fileStream.GetMD5Sum();
                            md5sums[item.Path] = md5item;
                        }

                        string md5other;
                        if (!md5sums.TryGetValue(other.Path, out md5other))
                        {
                            using (FileStream fileStream = File.OpenRead(other.Path))
                                md5other = fileStream.GetMD5Sum();
                            md5sums[other.Path] = md5other;
                        }

                        bool md5match = md5item.Equals(md5other, StringComparison.Ordinal);
                        if (queries.HasFlag(QueryType.EqualChecksumMD5) && md5match)
                        {
                            match |= QueryType.EqualChecksumMD5;
                        }
                        if (queries.HasFlag(QueryType.EqualFileNameDifferentChecksumMD5) && equalFilename && !md5match)
                        {
                            match |= QueryType.EqualFileNameDifferentChecksumMD5;
                        }
                    }

                    if (queries.HasFlag(QueryType.EqualChecksumSHA1) || queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA1))
                    {
                        string sha1item;
                        if (!sha1sums.TryGetValue(item.Path, out sha1item))
                        {
                            using (FileStream fileStream = File.OpenRead(item.Path))
                                sha1item = fileStream.GetSHA1Sum();
                            sha1sums[item.Path] = sha1item;
                        }

                        string sha1other;
                        if (!sha1sums.TryGetValue(other.Path, out sha1other))
                        {
                            using (FileStream fileStream = File.OpenRead(other.Path))
                                sha1other = fileStream.GetSHA1Sum();
                            sha1sums[other.Path] = sha1other;
                        }

                        bool sha1match = sha1item.Equals(sha1other, StringComparison.Ordinal);
                        if (queries.HasFlag(QueryType.EqualChecksumSHA1) && sha1match)
                        {
                            match |= QueryType.EqualChecksumSHA1;
                        }
                        if (queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA1) && equalFilename && !sha1match)
                        {
                            match |= QueryType.EqualFileNameDifferentChecksumSHA1;
                        }
                    }

                    if (queries.HasFlag(QueryType.EqualChecksumSHA256) || queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA256))
                    {
                        string sha256item;
                        if (!sha256sums.TryGetValue(item.Path, out sha256item))
                        {
                            using (FileStream fileStream = File.OpenRead(item.Path))
                                sha256item = fileStream.GetSHA256Sum();
                            sha256sums[item.Path] = sha256item;
                        }

                        string sha256other;
                        if (!sha256sums.TryGetValue(other.Path, out sha256other))
                        {
                            using (FileStream fileStream = File.OpenRead(other.Path))
                                sha256other = fileStream.GetSHA256Sum();
                            sha256sums[other.Path] = sha256other;
                        }

                        bool sha256match = sha256item.Equals(sha256other, StringComparison.Ordinal);
                        if (queries.HasFlag(QueryType.EqualChecksumSHA256) && sha256match)
                        {
                            match |= QueryType.EqualChecksumSHA256;
                        }
                        if (queries.HasFlag(QueryType.EqualFileNameDifferentChecksumSHA256) && equalFilename && !sha256match)
                        {
                            match |= QueryType.EqualFileNameDifferentChecksumSHA256;
                        }
                    }

                    if (queries.HasFlag(QueryType.LowResolution) || queries.HasFlag(QueryType.EqualFileNameDifferentResolution))
                    {
                        if (RequireMetaKey(MetaKey.Width, item) && RequireMetaKey(MetaKey.Height, item))
                        {
                            //const int limit = 960 * 1280;
                            const int resolutionLimit = 1024 * 768;

                            int resolutionItem = (int)item.Data[MetaKey.Width] * (int)item.Data[MetaKey.Height];
                            if (queries.HasFlag(QueryType.LowResolution) && resolutionItem <= resolutionLimit)
                            {
                                match |= QueryType.LowResolution;
                            }

                            if (queries.HasFlag(QueryType.EqualFileNameDifferentResolution) && equalFilename)
                            {
                                if (RequireMetaKey(MetaKey.Width, other) && RequireMetaKey(MetaKey.Height, other))
                                {
                                    int resolutionOther = (int)other.Data[MetaKey.Width] * (int)other.Data[MetaKey.Height];
                                    if (resolutionItem != resolutionOther)
                                    {
                                        match |= QueryType.EqualFileNameDifferentResolution;
                                    }
                                }
                            }
                        }
                    }

                    if (match != QueryType.None)
                    {
                        matches.Add(Tuple.Create(other.Path, match));
                    }
                }

                if (matches.Count > 0)
                {
                    allMatches[item.Path] = CleanupMatches(matches);
                }
            }

            QuerySummary result = new QuerySummary();

            result.matches = allMatches;
            return(result);
        }