<commit_before>﻿#region Usings

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ModInstallation.Annotations;
using ModInstallation.Implementations.DataClasses;
using ModInstallation.Implementations.Mods;
using ModInstallation.Interfaces;
using ModInstallation.Interfaces.Mods;
using ModInstallation.Util;
using Newtonsoft.Json;
using ReactiveUI;
using Semver;
using Splat;

#endregion

namespace ModInstallation.Implementations
{
    internal class InstalledMod : IInstalledModification
    {
        private readonly string _installPath;

        private readonly IModification _wrappedModification;

        public InstalledMod([NotNull] IModification wrappedModification, [NotNull] string installPath)
        {
            _wrappedModification = wrappedModification;
            _installPath = installPath;
        }

        #region IInstalledModification Members

        public event PropertyChangedEventHandler PropertyChanged
        {
            add { _wrappedModification.PropertyChanged += value; }
            remove { _wrappedModification.PropertyChanged -= value; }
        }

        public string Title
        {
            get { return _wrappedModification.Title; }
        }

        public SemVersion Version
        {
            get { return _wrappedModification.Version; }
        }

        public string Id
        {
            get { return _wrappedModification.Id; }
        }

        public IEnumerable<IPackage> Packages
        {
            get { return _wrappedModification.Packages; }
        }

        public string Description
        {
            get { return _wrappedModification.Description; }
        }

        public Uri LogoUri
        {
            get { return _wrappedModification.LogoUri; }
        }

        public string InstallPath
        {
            get { return _installPath; }
        }

        #endregion
    }

    [Export(typeof(ILocalModManager))]
    public class DefaultLocalModManager : ILocalModManager, IEnableLogger
    {
        private const string ModInfoFile = "mod.json";

        private readonly ReactiveList<IInstalledModification> _modifications;

        public DefaultLocalModManager()
        {
            _modifications = new ReactiveList<IInstalledModification>();
        }

        #region ILocalModManager Members

        public IEnumerable<IInstalledModification> Modifications
        {
            get { return _modifications; }
        }

        public string PackageDirectory { get; set; }

        public async Task AddPackageAsync(IPackage package)
        {
            var packageFile = Path.Combine(GetInstallationDirectory(package.ContainingModification), ModInfoFile);
            Modification modData;

            if (File.Exists(packageFile))
            {
                string content;
                using (var reader = File.OpenText(packageFile))
                {
                    content = await reader.ReadToEndAsync();
                }

                modData = await Task.Run(() => JsonConvert.DeserializeObject<Modification>(content));

                if (modData.packages.Any(p => p.name == package.Name))
                {
                    // the package is already present...
                    return;
                }

                // add the package
                modData.packages = modData.packages.Concat(package.ToDataClass().AsEnumerable());
            }
            else
            {
                modData = GetDataClass(package);
            }

            var json = await Task.Run(() => JsonConvert.SerializeObject(modData,
                new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Formatting = Formatting.Indented
                }));

            var directoryName = Path.GetDirectoryName(packageFile);
            if (directoryName != null && !Directory.Exists(directoryName))
            {
                Directory.CreateDirectory(directoryName);
            }

            using (var stream = File.Create(packageFile, 8 * 1024, FileOptions.Asynchronous))
            {
                using (var writer = new StreamWriter(stream))
                {
                    await writer.WriteAsync(json);
                }
            }

            var newData = DefaultModification.InitializeFromData(modData);

            if (newData == null)
            {
                return;
            }

            AddModification(newData);
        }

        public async Task ParseLocalModDataAsync()
        {
            _modifications.Clear();

            if (PackageDirectory == null)
            {
                return;
            }

            foreach (var modDir in Directory.EnumerateDirectories(PackageDirectory))
            {
                foreach (var versionDir in Directory.EnumerateDirectories(modDir))
                {
                    var modFile = Path.Combine(versionDir, ModInfoFile);

                    if (!File.Exists(modFile))
                    {
                        continue;
                    }

                    await ProcessModFile(modFile);
                }
            }
        }

        #endregion
<commit_msg>Don't crash when the package directory doesn't exist.<commit_after>﻿#region Usings

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ModInstallation.Annotations;
using ModInstallation.Implementations.DataClasses;
using ModInstallation.Implementations.Mods;
using ModInstallation.Interfaces;
using ModInstallation.Interfaces.Mods;
using ModInstallation.Util;
using Newtonsoft.Json;
using ReactiveUI;
using Semver;
using Splat;

#endregion

namespace ModInstallation.Implementations
{
    internal class InstalledMod : IInstalledModification
    {
        private readonly string _installPath;

        private readonly IModification _wrappedModification;

        public InstalledMod([NotNull] IModification wrappedModification, [NotNull] string installPath)
        {
            _wrappedModification = wrappedModification;
            _installPath = installPath;
        }

        #region IInstalledModification Members

        public event PropertyChangedEventHandler PropertyChanged
        {
            add { _wrappedModification.PropertyChanged += value; }
            remove { _wrappedModification.PropertyChanged -= value; }
        }

        public string Title
        {
            get { return _wrappedModification.Title; }
        }

        public SemVersion Version
        {
            get { return _wrappedModification.Version; }
        }

        public string Id
        {
            get { return _wrappedModification.Id; }
        }

        public IEnumerable<IPackage> Packages
        {
            get { return _wrappedModification.Packages; }
        }

        public string Description
        {
            get { return _wrappedModification.Description; }
        }

        public Uri LogoUri
        {
            get { return _wrappedModification.LogoUri; }
        }

        public string InstallPath
        {
            get { return _installPath; }
        }

        #endregion
    }

    [Export(typeof(ILocalModManager))]
    public class DefaultLocalModManager : ILocalModManager, IEnableLogger
    {
        private const string ModInfoFile = "mod.json";

        private readonly ReactiveList<IInstalledModification> _modifications;

        public DefaultLocalModManager()
        {
            _modifications = new ReactiveList<IInstalledModification>();
        }

        #region ILocalModManager Members

        public IEnumerable<IInstalledModification> Modifications
        {
            get { return _modifications; }
        }

        public string PackageDirectory { get; set; }

        public async Task AddPackageAsync(IPackage package)
        {
            var packageFile = Path.Combine(GetInstallationDirectory(package.ContainingModification), ModInfoFile);
            Modification modData;

            if (File.Exists(packageFile))
            {
                string content;
                using (var reader = File.OpenText(packageFile))
                {
                    content = await reader.ReadToEndAsync();
                }

                modData = await Task.Run(() => JsonConvert.DeserializeObject<Modification>(content));

                if (modData.packages.Any(p => p.name == package.Name))
                {
                    // the package is already present...
                    return;
                }

                // add the package
                modData.packages = modData.packages.Concat(package.ToDataClass().AsEnumerable());
            }
            else
            {
                modData = GetDataClass(package);
            }

            var json = await Task.Run(() => JsonConvert.SerializeObject(modData,
                new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Formatting = Formatting.Indented
                }));

            var directoryName = Path.GetDirectoryName(packageFile);
            if (directoryName != null && !Directory.Exists(directoryName))
            {
                Directory.CreateDirectory(directoryName);
            }

            using (var stream = File.Create(packageFile, 8 * 1024, FileOptions.Asynchronous))
            {
                using (var writer = new StreamWriter(stream))
                {
                    await writer.WriteAsync(json);
                }
            }

            var newData = DefaultModification.InitializeFromData(modData);

            if (newData == null)
            {
                return;
            }

            AddModification(newData);
        }

        public async Task ParseLocalModDataAsync()
        {
            _modifications.Clear();

            if (PackageDirectory == null)
            {
                return;
            }

            if (!Directory.Exists(PackageDirectory))
            {
                return;
            }

            foreach (var modDir in Directory.EnumerateDirectories(PackageDirectory))
            {
                foreach (var versionDir in Directory.EnumerateDirectories(modDir))
                {
                    var modFile = Path.Combine(versionDir, ModInfoFile);

                    if (!File.Exists(modFile))
                    {
                        continue;
                    }

                    await ProcessModFile(modFile);
                }
            }
        }

        #endregion

{'fraction_non_alphanumeric': 0.07059907834101382, 'fraction_numerical': 0.0009216589861751152, 'mean_word_length': 1.6726600985221676, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '258306', 'n_tokens_mistral': 2639, 'n_tokens_neox': 2502, 'n_words': 542}