public void Inc()
 {
     if (_Count++ % 1000 == 0)
     {
         PISave.Update(_Count);
     }
 }
Beispiel #2
0
        public void Activate()
        {
            using (ProgressDialog progressDlg = new ProgressDialog())
            {
                progressDlg.StartPosition = FormStartPosition.CenterScreen;
                progressDlg.Show();

                ProgressItem piPrepare = progressDlg.Add("Prepare ...", "get species", 0, 3);
                // retrouve la liste de toutes les especes / sous especes
                List <TaxonTreeNode> Species = new List <TaxonTreeNode>();
                TaxonUtils.OriginalRoot.GetAllChildrenRecursively(Species, ClassicRankEnum.Espece);
                piPrepare.Update(1, "get sub species");
                List <TaxonTreeNode> SubSpecies = new List <TaxonTreeNode>();
                TaxonUtils.OriginalRoot.GetAllChildrenRecursively(SubSpecies, ClassicRankEnum.SousEspece);
                piPrepare.Update(2, "all images name (can be long)");
                // et la liste des fichiers dans le répertoires d'images
                string PathImages  = TaxonImages.Manager.Path;
                int    TotalImages = 0;
                Dictionary <string, bool> FileUsed = new Dictionary <string, bool>();
                Directory.GetFiles(PathImages, "*.jpg", SearchOption.AllDirectories).ToList().ForEach(f => { FileUsed[f.ToLower()] = false; TotalImages++; });
                piPrepare.Update(3, "init done");

                ProgressItem         piSpecies           = progressDlg.Add("Prepare ...", "get species", 0, Species.Count);
                List <TaxonTreeNode> SpeciesWithImage    = new List <TaxonTreeNode>();
                List <TaxonTreeNode> SpeciesWithBadImage = new List <TaxonTreeNode>();
                List <TaxonTreeNode> SpeciesWithoutImage = new List <TaxonTreeNode>();
                int count = 0;
                foreach (TaxonTreeNode node in Species)
                {
                    piSpecies.Update(++count);
                    if (node.Desc.Images == null)
                    {
                        SpeciesWithoutImage.Add(node);
                        continue;
                    }

                    bool badImage  = false;
                    bool goodImage = false;
                    foreach (TaxonImageDesc imageDesc in node.Desc.Images)
                    {
                        if (imageDesc.IsALink)
                        {
                            continue;
                        }
                        string path = imageDesc.GetPath(node.Desc).ToLower();
                        bool   used;
                        if (!FileUsed.TryGetValue(path, out used))
                        {
                            badImage = true;
                        }
                        else
                        {
                            goodImage = true;
                            if (used)
                            {
                                Console.WriteLine("image " + path + " used several time");
                            }
                            FileUsed[path] = true;
                        }
                    }
                    if (badImage)
                    {
                        SpeciesWithBadImage.Add(node);
                    }
                    if (goodImage)
                    {
                        SpeciesWithImage.Add(node);
                    }
                }

                ProgressItem         piSubSpecies           = progressDlg.Add("Prepare ...", "get species", 0, Species.Count);
                List <TaxonTreeNode> SubSpeciesWithImage    = new List <TaxonTreeNode>();
                List <TaxonTreeNode> SubSpeciesWithBadImage = new List <TaxonTreeNode>();
                List <TaxonTreeNode> SubSpeciesWithoutImage = new List <TaxonTreeNode>();
                count = 0;
                foreach (TaxonTreeNode node in SubSpecies)
                {
                    piSubSpecies.Update(++count);
                    if (node.Desc.Images == null)
                    {
                        SubSpeciesWithoutImage.Add(node);
                        continue;
                    }

                    bool badImage  = false;
                    bool goodImage = false;
                    foreach (TaxonImageDesc imageDesc in node.Desc.Images)
                    {
                        if (imageDesc.IsALink)
                        {
                            continue;
                        }
                        string path = imageDesc.GetPath(node.Desc).ToLower();
                        bool   used;
                        if (!FileUsed.TryGetValue(path, out used))
                        {
                            badImage = true;
                        }
                        else
                        {
                            goodImage = true;
                            if (used)
                            {
                                Console.WriteLine("image " + path + " used several time");
                            }
                            FileUsed[path] = true;
                        }
                    }
                    if (badImage)
                    {
                        SubSpeciesWithBadImage.Add(node);
                    }
                    if (goodImage)
                    {
                        SubSpeciesWithImage.Add(node);
                    }
                }

                List <string> unusedfiles = FileUsed.Where(p => !p.Value).Select(p => p.Key).ToList();

                string message = "Check unused image summary : \n\n";
                message += String.Format("    Total species     : {0}, {1} with images, {2} with bad images, {3} without\n", Species.Count, SpeciesWithImage.Count, SpeciesWithBadImage.Count, SpeciesWithoutImage.Count);
                message += String.Format("    Total sub/species : {0}, {1} with images, {2} with bad images, {3} without\n\n", SubSpecies.Count, SubSpeciesWithImage.Count, SubSpeciesWithBadImage.Count, SubSpeciesWithoutImage.Count);
                message += String.Format("    Total images      : {0}, {1} are unused\n\n", TotalImages, unusedfiles.Count);
                message += String.Format("for more details, look at CheckUnusedImages.log file");
                Loggers.WriteInformation(LogTags.Image, message);

                try
                {
                    string file = Path.Combine(TaxonUtils.GetLogPath(), "CheckUnusedImages.log");
                    if (File.Exists(file))
                    {
                        File.Delete(file);
                    }
                    using (StreamWriter outfile = new StreamWriter(file))
                    {
                        outfile.WriteLine("CheckUnusedImages result ( " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " )\n");
                        outfile.WriteLine(string.Format("Unused images ( {0} ) :", unusedfiles.Count));
                        unusedfiles.ForEach(f => outfile.WriteLine(string.Format("    " + f)));
                        outfile.WriteLine("\n");

                        outfile.WriteLine(string.Format("Species without bad images ( {0} ) :", SpeciesWithBadImage.Count));
                        foreach (TaxonTreeNode node in SpeciesWithBadImage)
                        {
                            outfile.WriteLine(string.Format("    " + node.Desc.RefMultiName.Main));
                        }
                        outfile.WriteLine("\n");

                        outfile.WriteLine(string.Format("Sub/Species with bad images ( {0} ) :", SubSpeciesWithBadImage.Count));
                        foreach (TaxonTreeNode node in SubSpeciesWithBadImage)
                        {
                            outfile.WriteLine(string.Format("    " + node.Desc.RefMultiName.Main));
                        }

                        outfile.WriteLine("\n");
                    }
                }
                catch (Exception e)
                {
                    string error = "Exception while saving results in CheckUnusedImages.log: \n\n";
                    error += e.Message;
                    if (e.InnerException != null)
                    {
                        error += "\n" + e.InnerException.Message;
                    }
                    Loggers.WriteError(LogTags.Image, error);
                }
            }
        }
        public void Activate()
        {
            DateTime ts_Start = DateTime.Now;

            using (ProgressDialog progressDlg = new ProgressDialog())
            {
                progressDlg.StartPosition = FormStartPosition.CenterScreen;
                progressDlg.Show();

                // retrouve la liste de toutes les especes / sous especes
                ProgressItem         piPrepare = progressDlg.Add("Prepare ...", "get species", 0, 4);
                List <TaxonTreeNode> Species   = new List <TaxonTreeNode>();
                TaxonUtils.OriginalRoot.GetAllChildrenRecursively(Species, ClassicRankEnum.Espece);
                piPrepare.Update(1, "get sub species");
                TaxonUtils.OriginalRoot.GetAllChildrenRecursively(Species, ClassicRankEnum.SousEspece);
                piPrepare.Update(2, "init");

                int beforeWith    = 0;
                int beforeImages  = 0;
                int beforeWithout = 0;

                DateTime ts_StartDico = DateTime.Now;
                Dictionary <string, TaxonTreeNode> dico = new Dictionary <string, TaxonTreeNode>();
                foreach (TaxonTreeNode node in Species)
                {
                    if (node.Desc.Images != null && node.Desc.Images.Count != 0)
                    {
                        beforeWith++;
                        beforeImages += node.Desc.Images.Count;
                    }
                    else
                    {
                        beforeWithout++;
                    }

                    dico[node.Desc.RefMultiName.Main.ToLower()] = node;
                }

                piPrepare.Update(3, "clear");
                TaxonUtils.OriginalRoot.ParseNodeDesc((d) => { d.Images = null; });
                piPrepare.Update(4, "end");
                piPrepare.End();

                DateTime ts_StartParseCollection = DateTime.Now;

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

                ProgressItem piCollections = progressDlg.Add("Parse collections ...", "", 0, TaxonImages.Manager.CollectionsEnumerable().Count());
                foreach (ImageCollection collection in TaxonImages.Manager.CollectionsEnumerable())
                {
                    piCollections.Update(piCollections.Current + 1, collection.Name);

                    if (!Directory.Exists(collection.Path))
                    {
                        continue;
                    }
                    IEnumerable <string> files = Directory.EnumerateFiles(collection.Path, "*.jpg");

                    int  count        = 10000;
                    Task getCountTask = Task.Factory.StartNew(() => { count = files.Count(); });

                    int          counter  = 0;
                    ProgressItem piPhotos = progressDlg.Add("Parse " + collection.Name + " photos ...", "", 0, count - 1);
                    foreach (string file in files)
                    {
                        string name = Path.GetFileNameWithoutExtension(file);

                        counter++;
                        if (counter == 10)
                        {
                            counter = 0;
                            if (getCountTask != null)
                            {
                                if (getCountTask.IsCompleted)
                                {
                                    piPhotos.Max = count - 1;
                                    getCountTask = null;
                                }
                                else if (piPhotos.Max < piPhotos.Current + 10)
                                {
                                    piPhotos.Max += 10000;
                                }
                            }
                            piPhotos.Update(piPhotos.Current + 10, name);
                        }

                        TaxonImages.SplitImageFilenameResult result = TaxonImages.Manager.SplitImageFilename(file, false, collection);
                        if (result == null)
                        {
                            badFormatFilenames.Add(file);
                            continue;
                        }

                        name = result.TaxonName.ToLower();

                        if (dico.ContainsKey(name))
                        {
                            if (dico[name].Desc.Images == null)
                            {
                                dico[name].Desc.Images = new List <TaxonImageDesc>();
                            }
                            dico[name].Desc.Images.Add(result.Desc);
                        }
                    }
                    piPhotos.End();

                    // treat xmls
                    foreach (var pair in collection.AllLinks)
                    {
                        ImagesLinks list = pair.Value;

                        for (int i = 0; i < list.Count; i++)
                        {
                            ImageLink link = list[i];
                            if (dico.TryGetValue(link.Key.ToLower(), out TaxonTreeNode node))
                            {
                                TaxonImageDesc desc = new TaxonImageDesc
                                {
                                    CollectionId = collection.Id,
                                    Secondary    = false,
                                    LinksId      = pair.Key,
                                    Index        = i
                                };

                                if (node.Desc.Images == null)
                                {
                                    node.Desc.Images = new List <TaxonImageDesc>();
                                }
                                node.Desc.Images.Add(desc);
                            }
                        }
                    }

                    foreach (var reference in collection.DistantReferences)
                    {
                        if (dico.TryGetValue(reference.TaxonName.ToLower(), out TaxonTreeNode node))
                        {
                            TaxonImageDesc desc = new TaxonImageDesc
                            {
                                CollectionId = collection.Id,
                                Secondary    = false,
                                LinksId      = 0,
                                Index        = reference.Index
                            };

                            if (node.Desc.Images == null)
                            {
                                node.Desc.Images = new List <TaxonImageDesc>();
                            }
                            node.Desc.Images.Add(desc);
                        }
                    }
                }

                DateTime ts_StartFinalise = DateTime.Now;

                int afterWith    = 0;
                int afterImages  = 0;
                int afterWithout = 0;

                foreach (TaxonTreeNode node in Species)
                {
                    if (node.Desc.Images != null)
                    {
                        afterWith++;
                        afterImages += node.Desc.Images.Count;
                    }
                    else
                    {
                        afterWithout++;
                    }
                }

                DateTime ts_End = DateTime.Now;

                string message = "Update image flag : \n\n";
                message += String.Format("    Total with image     : {0} referencing {1} images, (before: {2} referencing {3} images)\n", afterWith, afterImages, beforeWith, beforeImages);
                message += String.Format("    Total without image  : {0}, (before: {1})\n\n", afterWithout, beforeWithout);
                message += String.Format("    Badly formatted files: {0}\n", badFormatFilenames.Count);
                message += String.Format("    {0} ms to get taxons\n", (ts_StartDico - ts_Start).Milliseconds);
                message += String.Format("    {0} ms to fill dico\n", (ts_StartParseCollection - ts_StartDico).Milliseconds);
                message += String.Format("    {0} ms to parse collections\n", (ts_StartFinalise - ts_StartParseCollection).Milliseconds);
                message += String.Format("    {0} ms to finalize taxons\n", (ts_End - ts_StartFinalise).Milliseconds);
                message += String.Format("Dumped in UpdateImages.log file");
                Loggers.WriteInformation(LogTags.Image, message);

                string logfile = Path.Combine(TaxonUtils.GetLogPath(), "UpdateImages.log");
                if (File.Exists(logfile))
                {
                    File.Delete(logfile);
                }
                using (StreamWriter log = new StreamWriter(logfile))
                {
                    log.WriteLine("UpdateImages result ( " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + " )\n");
                    log.WriteLine(message);
                    log.WriteLine("");
                    log.WriteLine("Files with bad format names detected:\n");
                    foreach (string filename in badFormatFilenames)
                    {
                        log.WriteLine("    " + filename);
                    }
                }
            }

            TaxonUtils.OriginalRoot.UpdateAvailableImages();
            TaxonControlList.OnAvailableImagesChanged();
        }
Beispiel #4
0
        public void Activate()
        {
            using (ProgressDialog progressDlg = new ProgressDialog())
            {
                progressDlg.StartPosition = FormStartPosition.CenterScreen;
                progressDlg.Show();

                ProgressItem piPrepare = progressDlg.Add("Prepare ...", "get taxon with images", 0, 2);
                // retrouve la liste de toutes les especes / sous especes
                List <TaxonDesc> Nodes = new List <TaxonDesc>();
                TaxonUtils.OriginalRoot.ParseNodeDesc((d) => { if (d.HasImage)
                                                               {
                                                                   Nodes.Add(d);
                                                               }
                                                      });
                piPrepare.Update(1, "all images name (can be long)");
                // et la liste des fichiers dans le répertoires d'images
                string PathImages  = TaxonImages.Manager.Path;
                int    TotalImages = 0;
                Dictionary <string, bool> FileUsed = new Dictionary <string, bool>();
                Directory.GetFiles(PathImages, "*.jpg", SearchOption.AllDirectories).ToList().ForEach(f => { FileUsed[f.ToLower()] = false; TotalImages++; });
                piPrepare.Update(2, "init done");

                ProgressItem piTaxonDesc = progressDlg.Add("Parse Taxon with images ...", "", 0, Nodes.Count);
                int          count       = 0;
                foreach (TaxonDesc desc in Nodes)
                {
                    piTaxonDesc.Update(++count);
                    foreach (TaxonImageDesc imageDesc in desc.Images)
                    {
                        if (imageDesc.IsALink)
                        {
                            continue;
                        }
                        string path = imageDesc.GetPath(desc).ToLower();
                        if (FileUsed.ContainsKey(path))
                        {
                            FileUsed[path] = true;
                        }
                    }
                }

                List <string> unusedfiles = FileUsed.Where(p => !p.Value).Select(p => p.Key).ToList();
                ProgressItem  piFinder    = progressDlg.Add("Init finder...", "", 0, 1);
                TaxonSearch   finder      = new TaxonSearch(TaxonUtils.OriginalRoot, true, true);
                piFinder.Update(1);

                int noTaxonFound       = 0;
                int severalTaxonFound  = 0;
                int renamedFiles       = 0;
                int sameName           = 0;
                int errorWhileRenaming = 0;

                string logfile = Path.Combine(TaxonUtils.GetLogPath(), "ImageRenameSynonyms.log");
                if (File.Exists(logfile))
                {
                    File.Delete(logfile);
                }
                using (StreamWriter log = new StreamWriter(logfile))
                {
                    ProgressItem piUnused = progressDlg.Add("Treat unused images ...", "", 0, unusedfiles.Count);
                    foreach (string filename in unusedfiles)
                    {
                        piUnused.Inc();
                        TaxonImages.SplitImageFilenameResult splitResult = TaxonImages.Manager.SplitImageFilename(filename);
                        if (splitResult == null)
                        {
                            continue;
                        }

                        List <TaxonTreeNode> nodes = finder.FindAll(splitResult.TaxonName);
                        string textline            = "[" + (nodes == null ? 0 : nodes.Count) + "] " + splitResult.TaxonName + ": ";
                        if (nodes == null || nodes.Count == 0)
                        {
                            noTaxonFound++;
                            textline += "no taxon found";
                        }
                        else if (nodes.Count > 1)
                        {
                            severalTaxonFound++;
                            textline += "too many taxons found";
                        }
                        else if (filename.ToLower() == splitResult.Desc.GetPath(nodes[0].Desc).ToLower())
                        {
                            sameName++;
                            textline += "same name, probably unused due to rank";
                        }
                        else
                        {
                            TaxonTreeNode  node = nodes[0];
                            TaxonImageDesc desc = splitResult.Desc;
                            desc.FillForNewFile(node.Desc);
                            string newFilename = desc.GetPath(node.Desc);
                            textline += " rename " + System.IO.Path.GetFileName(filename) + " in " + System.IO.Path.GetFileName(newFilename);
                            try
                            {
                                System.IO.File.Move(filename, newFilename);
                                renamedFiles++;
                            }
                            catch (System.Exception e)
                            {
                                textline += "[error] " + e.Message;
                                errorWhileRenaming++;
                            }
                        }
                        log.WriteLine(textline);
                    }
                }

                string message = "Rename unused file using synonyms name : \n\n";
                message += String.Format("    Total treated files: {0}\n", unusedfiles.Count);
                message += String.Format("    No match: {0}\n", noTaxonFound);
                message += String.Format("    Several matches: {0}\n", severalTaxonFound);
                message += String.Format("    New name is same as unused: {0}\n", sameName);
                message += String.Format("    Renamed files: {0}\n", renamedFiles);
                message += String.Format("    Error renaming: {0}\n", errorWhileRenaming);
                message += String.Format("Same renaming occurs, do not forget to update images\n");
                message += String.Format("for more details, look at ImageRenameSynonyms.log file");
                Loggers.WriteInformation(LogTags.Image, message);
            }
        }
Beispiel #5
0
        public void Activate()
        {
            Task taskDeleteOldCollection             = null;
            Task taskGatherExistentSpecies           = null;
            Dictionary <string, int> existentSpecies = new Dictionary <string, int>();

            ImageCollection arkiveCollection = TaxonImages.Manager.GetByName("Arkive");

            if (arkiveCollection != null)
            {
                QuestionDialog dlg = new QuestionDialog
                                     (
                    "Arkive collection already exists !\nWhat do you want to do ?",
                    "Confirm ... ",
                    new TaxonDialog.AnswersDesc().
                    Add("Delete", "delete all content of old arkive collection", 0).
                    Add("Merge", "import only image for species newly found", 1).
                    Add("Cancel", "stop the generation of collection", 2)
                                     );
                dlg.ShowDialog();
                OneAnswerDesc answer = dlg.Answer;

                if (answer == null || answer.ID == 2)
                {
                    return;
                }

                /*string message = "Arkive collection exist, remove it ?";
                 * DialogResult result = MessageBox.Show(message, "Confirm ...", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                 * if (result == DialogResult.Cancel)
                 *  return;*/

                if (answer.ID == 0)
                {
                    taskDeleteOldCollection = Task.Factory.StartNew(() => Directory.Delete(arkiveCollection.Path, true));
                }
                else
                {
                    taskGatherExistentSpecies = Task.Factory.StartNew(() =>
                    {
                        foreach (string file in Directory.EnumerateFiles(arkiveCollection.Path))
                        {
                            string species = Path.GetFileNameWithoutExtension(file).Split('_')[0];
                            if (!existentSpecies.ContainsKey(species))
                            {
                                existentSpecies[species] = 0;
                            }
                            existentSpecies[species] = existentSpecies[species] + 1;
                        }
                    });
                }
            }

            string folderArkive;

            using (var fbd = new FolderBrowserDialog())
            {
                fbd.Description  = "Select Folder where Arkive images are stored";
                fbd.SelectedPath = TaxonUtils.GetTaxonPath();
                DialogResult result = fbd.ShowDialog();
                if (result != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath))
                {
                    return;
                }
                folderArkive = fbd.SelectedPath;
            }

            int lengthFolderArkive = folderArkive.Length;

            using (ProgressDialog progressDlg = new ProgressDialog())
            {
                progressDlg.StartPosition = FormStartPosition.CenterScreen;
                progressDlg.Show();

                ProgressItem piInitSearch = progressDlg.Add("Initialize searching", "", 0, 2);
                TaxonSearch  searching    = new TaxonSearch(TaxonUtils.OriginalRoot, true, true);
                piInitSearch.Update(1);
                string[] foldersLevel1 = Directory.GetDirectories(folderArkive);
                piInitSearch.Update(2);
                piInitSearch.End();

                Dictionary <string, string>        unknownFolder = new Dictionary <string, string>();
                Dictionary <string, TaxonTreeNode> knownFolder   = new Dictionary <string, TaxonTreeNode>();
                int missedPhotos          = 0;
                int importedPhotos        = 0;
                int alreadyImportedPhotos = 0;
                int newlyImportedPhotos   = 0;

                ProgressItem piParse = progressDlg.Add("Parse arkive folders", "", 0, foldersLevel1.Length);
                for (uint i = 0; i < foldersLevel1.Length; i++)
                {
                    piParse.Update(i, foldersLevel1[i].Substring(lengthFolderArkive + 1));
                    int folder1Length = foldersLevel1[i].Length + 1;

                    string[] foldersLevel2 = Directory.GetDirectories(foldersLevel1[i]);
                    foreach (string folder2 in foldersLevel2)
                    {
                        //if (folder2.ToLower().Contains("acropora"))
                        //    Console.WriteLine(folder2);

                        string[] photos = Directory.GetFiles(folder2, "*.jpg");
                        if (photos.Length == 0)
                        {
                            continue;
                        }

                        string        name = folder2.Substring(folder1Length).Replace('-', ' ').ToLower().Trim();
                        TaxonTreeNode node = searching.FindOne(name);
                        if (node == null)
                        {
                            unknownFolder[folder2] = name;
                            missedPhotos          += photos.Length;
                        }
                        else
                        {
                            knownFolder[folder2] = node;
                        }
                    }
                }
                piParse.Update(piParse.Max, knownFolder.Count.ToString() + " found, " + unknownFolder.Count.ToString() + " not.");

                if (taskDeleteOldCollection != null && !taskDeleteOldCollection.IsCompleted)
                {
                    ProgressItem piClean = progressDlg.Add("Clean old collection", "", 0, 1);
                    taskDeleteOldCollection.Wait();
                    piClean.Update(1);
                    piClean.End();
                }

                if (taskGatherExistentSpecies != null && !taskGatherExistentSpecies.IsCompleted)
                {
                    ProgressItem piAnalyseOld = progressDlg.Add("Analyse old collection", "", 0, 1);
                    taskGatherExistentSpecies.Wait();
                    piAnalyseOld.Update(1);
                    piAnalyseOld.End();
                }

                arkiveCollection = TaxonImages.Manager.GetOrCreateCollection("Arkive");
                if (arkiveCollection == null)
                {
                    return;
                }
                arkiveCollection.Desc  = "Collection generated from images taken from Arkive site : http://www.arkive.org";
                arkiveCollection.Desc += "Generated date : " + DateTime.Now.ToString();
                arkiveCollection.SaveInfos();
                ProgressItem piPopulate = progressDlg.Add("Populate collection", "", 0, knownFolder.Count);
                foreach (KeyValuePair <string, TaxonTreeNode> pair in knownFolder)
                {
                    string speciesName = pair.Value.Desc.RefMultiName.Main;
                    piPopulate.Update(piPopulate.Current + 1, speciesName);

                    string[] photos = Directory.GetFiles(pair.Key, "*.jpg");
                    importedPhotos += photos.Length;

                    if (existentSpecies.ContainsKey(speciesName))
                    {
                        if (existentSpecies[speciesName] == photos.Length)
                        {
                            alreadyImportedPhotos += photos.Length;
                            continue;
                        }
                        File.Delete(arkiveCollection.Path + Path.DirectorySeparatorChar + speciesName + "*.*");
                    }

                    newlyImportedPhotos += photos.Length;

                    for (int index = 0; index < photos.Length; index++)
                    {
                        string newName = speciesName + "_" + index.ToString() + ".jpg";
                        File.Copy(photos[index], arkiveCollection.Path + Path.DirectorySeparatorChar + newName);
                    }
                }
                piPopulate.Update(piPopulate.Max, importedPhotos.ToString() + " photos imported.");

                string message0 = (unknownFolder.Count + knownFolder.Count).ToString() + " total folders found\n";
                string message1 = knownFolder.Count.ToString() + " with associated taxons ( " + importedPhotos.ToString() + " photos imported )";
                if (newlyImportedPhotos != importedPhotos)
                {
                    message1 += " ( merging : " + newlyImportedPhotos + " new photos";
                }
                string message2 = unknownFolder.Count.ToString() + " names not found ( " + missedPhotos.ToString() + " photos left behind )";
                string message  = message0 + "\n" + message1 + "\n" + message2 + "\n\n" + "for more details, look at GenerateArkiveCollection.log file";
                if (unknownFolder.Count > 0)
                {
                    message += "\nA list of taxons is generated with all name not found : " + Path.Combine(TaxonList.GetFolder(), "ArkiveNames.txt");
                }
                Loggers.WriteInformation(LogTags.Data, message);

                try
                {
                    List <KeyValuePair <string, string> > unknowns = unknownFolder.ToList();
                    unknowns.Sort((x, y) => x.Value.CompareTo(y.Value));

                    string file = Path.Combine(TaxonUtils.GetLogPath(), "GenerateArkiveCollection.log");
                    if (File.Exists(file))
                    {
                        File.Delete(file);
                    }
                    using (StreamWriter outfile = new StreamWriter(file))
                    {
                        outfile.WriteLine("GenerateArkiveCollection results:");
                        outfile.WriteLine();
                        outfile.WriteLine("  " + message0);
                        outfile.WriteLine("  " + message1);
                        outfile.WriteLine("  " + message2);
                        outfile.WriteLine();
                        if (unknowns.Count > 0)
                        {
                            outfile.WriteLine("List of not found names:");
                            outfile.WriteLine();

                            int maxLength = 0;
                            foreach (KeyValuePair <string, string> pair in unknowns)
                            {
                                maxLength = Math.Max(maxLength, pair.Value.Length);
                            }
                            foreach (KeyValuePair <string, string> pair in unknowns)
                            {
                                outfile.WriteLine("  " + pair.Value.PadRight(maxLength) + " => " + pair.Key);
                            }
                            outfile.WriteLine();
                        }
                    }

                    if (unknowns.Count > 0)
                    {
                        file = Path.Combine(TaxonList.GetFolder(), "ArkiveNames.txt");
                        if (File.Exists(file))
                        {
                            File.Delete(file);
                        }
                        using (StreamWriter outfile = new StreamWriter(file))
                        {
                            foreach (KeyValuePair <string, string> pair in unknowns)
                            {
                                outfile.WriteLine(pair.Value);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    string error = "Exception while saving results in GenerateArkiveCollection.log: \n\n";
                    error += e.Message;
                    if (e.InnerException != null)
                    {
                        error += "\n" + e.InnerException.Message;
                    }
                    Loggers.WriteError(LogTags.Data, error);
                }
            }
        }