public ShellViewModel(IWindowManager windowManager,
                              [ImportMany] IEnumerable <IMailHost> mailHosts,
                              [ImportMany] IEnumerable <IUrlShortening> urlShortenings,
                              [ImportMany] IEnumerable <IFileHost> fileHosts)
        {
            var version = Assembly.GetExecutingAssembly().GetName().Version;

            this.DisplayName = string.Format("Sharing Worker {0}.{1}.{2}", version.Major, version.Minor, version.Build);

            UploadResults = new BindableCollection <UploadInfo>();

            ImgChili = new ImgChili();
            LoadConfig(ImgChili);
            ImgRock = new ImgRock();
            LoadConfig(ImgRock);
            PixSense = new PixSense();
            LoadConfig(PixSense);

            GetMega       = bool.Parse(((NameValueCollection)ConfigurationManager.GetSection("Mega"))["Enabled"]);
            GetUploadGIG  = bool.Parse(((NameValueCollection)ConfigurationManager.GetSection("UploadGIG"))["Enabled"]);
            GetRapidgator = bool.Parse(((NameValueCollection)ConfigurationManager.GetSection("Rapidgator"))["Enabled"]);

            Blogger.PostProgressEvent += Blogger_PostProgressEvent;

            CompressToRar = true;
            GetThumbnail  = true;
            GetCover      = true;
            RarList       = new RarListViewModel();

            MailHosts      = new List <IMailHost>(mailHosts);
            UrlShortenings = new List <IUrlShortening>(urlShortenings.OrderBy(u => u.Order));
            FileHosts      = new List <IFileHost>(fileHosts);
            foreach (var fileHost in FileHosts)
            {
                fileHost.LoadConfig();
            }

            this.windowManager = windowManager;
        }
        public async void Upload()
        {
            if (!UploadResults.Any())
            {
                return;
            }

            IsUploadFinished = false;
            Message          = "";
            Blogger.StartPosting();

            UploadInfo.RemoveSignature(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\west.txt");
            UploadInfo.RemoveSignature(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\west_pornbb.txt");

            var rnd = new Random();

            foreach (var uploadInfo in UploadResults)
            {
                var megaLinks = MEGA.GetEnabled ? await MEGA.GetLinks(uploadInfo.Id) : Enumerable.Empty <string>();

                var rapidgatorLinks = Rapidgator.GetEnabled ? await Rapidgator.GetLinks(uploadInfo.Id) : Enumerable.Empty <string>();

                if (MEGA.GetEnabled && !megaLinks.Any())
                {
                    uploadInfo.Id += "\n(No MEGA links!)";
                    continue;
                }
                if (Rapidgator.GetEnabled && !rapidgatorLinks.Any())
                {
                    uploadInfo.Id += "\n(No Rapidgator links!)";
                    continue;
                }

                if (MEGA.GetEnabled && Rapidgator.GetEnabled && megaLinks.Count() != rapidgatorLinks.Count())
                {
                    uploadInfo.Id += "\n(Missing some Mega/Rapidgator links!)";
                    continue;
                }

                // TODO: refactor
                var zippyshareLinks = Enumerable.Empty <string>();
                var linkSuccess     = true;
                foreach (var fileHost in FileHosts)
                {
                    if (!fileHost.Enabled)
                    {
                        continue;
                    }

                    var links = await fileHost.GetLinks(uploadInfo.Id);

                    if (!links.Any())
                    {
                        uploadInfo.Id += $"\n(No {fileHost.Name} links!)";
                        linkSuccess    = false;
                        break;
                    }
                    if (MEGA.GetEnabled && megaLinks.Count() != links.Count)
                    {
                        uploadInfo.Id += $"\n(Missing some Mega/{fileHost.Name} links!)";
                        linkSuccess    = false;
                        break;
                    }

                    zippyshareLinks = links;
                }
                if (!linkSuccess)
                {
                    continue;
                }

                var uploadTasks = new List <Task <List <string> > >();

                if (ImgChili.LoggedIn && ImgChili.Enabled)
                {
                    uploadTasks.Add(ImgChili.Upload(uploadInfo.UploadList));
                }
                if (ImgRock.LoggedIn && ImgRock.Enabled)
                {
                    uploadTasks.Add(ImgRock.Upload(uploadInfo.UploadList));
                }
                if (PixSense.LoggedIn && PixSense.Enabled)
                {
                    uploadTasks.Add(PixSense.Upload(uploadInfo.UploadList));
                }

                var taskCount = uploadTasks.Count;

                var uploadCount = 0;
                while (uploadTasks.Count > 0)
                {
                    try
                    {
                        var finishedTask = await Task.WhenAny(uploadTasks);

                        uploadTasks.Remove(finishedTask);

                        var links = await Task.Run(() => finishedTask);

                        if (links == null)
                        {
                            continue;
                        }

                        if (links[0].Contains("imgchili"))
                        {
                            uploadInfo.WebLinks1   = links[0].Trim();
                            uploadInfo.ForumLinks1 = ToLowerForumCode(links[1].Trim());
                            uploadCount++;
                        }
                        else if (links[0].Contains("imgrock"))
                        {
                            uploadInfo.WebLinks2   = links[0].Trim();
                            uploadInfo.ForumLinks2 = links[1].Trim();
                            uploadCount++;
                        }
                        else if (links[0].Contains("pixsense") || links[0].Contains("iceimg") || links[0].Contains("imgvip"))
                        {
                            uploadInfo.WebLinks3   = links[0].Trim();
                            uploadInfo.ForumLinks3 = links[1].Trim();
                            uploadCount++;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Contains(ImgChili.Name))
                        {
                            uploadInfo.WarningBrush1 = Brushes.Red;
                        }
                        else if (ex.Message.Contains(ImgRock.Name))
                        {
                            uploadInfo.WarningBrush2 = Brushes.Red;
                        }
                        else if (ex.Message.Contains(PixSense.Name))
                        {
                            uploadInfo.WarningBrush3 = Brushes.Red;
                        }

                        uploadInfo.IdColor = Colors.Red;
                        Message            = ex.InnerException.Message;
                    }
                }

                try
                {
                    if (Rapidgator.GetEnabled)
                    {
                        await uploadInfo.WriteOutput(string.Join("\\n", megaLinks), string.Join("\\n", rapidgatorLinks));
                    }
                    else if (Zippyshare.Enabled)
                    {
                        await uploadInfo.WriteOutput(string.Join("\\n", megaLinks), string.Join("\\n", zippyshareLinks));
                    }
                    else
                    {
                        await uploadInfo.WriteOutput(string.Join("\\n", megaLinks), string.Join("\\n", rapidgatorLinks));
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(string.Format("Failed to write output: {0}", uploadInfo.Id), ex);
                    if (ex.InnerException != null)
                    {
                        Logger.Error(string.Format("Failed to write output (InnerException): {0}", uploadInfo.Id), ex.InnerException);
                    }
                }

                // Delete or Move images
                if (uploadCount == taskCount)
                {
                    foreach (var image in uploadInfo.UploadList)
                    {
                        try
                        {
                            File.Delete(image.Path);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(string.Format("Failed to delete images: {0}", uploadInfo.Id), ex);
                        }
                    }
                }
                else
                {
                    foreach (var image in uploadInfo.UploadList)
                    {
                        try
                        {
                            var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Handled");
                            if (!Directory.Exists(dir))
                            {
                                Directory.CreateDirectory(dir);
                            }
                            File.Move(image.Path, Path.Combine(dir, Path.GetFileName(image.Path)));
                        }
                        catch (Exception ex)
                        {
                            Logger.ErrorException(string.Format("Failed to move images: {0}", uploadInfo.Id), ex);
                        }
                    }
                }

                // Move files
                foreach (var path in UploadInfo.UploadPaths)
                {
                    if (!Directory.Exists(path))
                    {
                        continue;
                    }
                    var files = Directory.GetFiles(path, string.Format("{0}*.part*.rar", uploadInfo.Id), SearchOption.TopDirectoryOnly);
                    foreach (var file in files)
                    {
                        var fileInfo = new FileInfo(file);
                        var donePath = Path.Combine(fileInfo.DirectoryName, "Done");
                        if (!Directory.Exists(donePath))
                        {
                            Directory.CreateDirectory(donePath);
                        }

                        try
                        {
                            File.Move(file, Path.Combine(donePath, fileInfo.Name));
                        }
                        catch (IOException)
                        {
                            break;
                        }
                    }
                    if (files.Any())
                    {
                        break;
                    }
                }

                SpinWait.SpinUntil(() => false, rnd.Next(600, 1200));
            }

            UploadInfo.WriteSignature(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\west.txt");
            UploadInfo.WriteSignature(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\west_pornbb.txt");
            IsUploadFinished = true;
            Message          = "Upload done";
        }
        private async Task <bool> Login(LoginFlag flag)
        {
            Message = "";
            try
            {
                var loginTasks = new List <Task>();
                if (!ImgChili.LoggedIn && flag.HasFlag(LoginFlag.ImgChili))
                {
                    loginTasks.Add(ImgChili.LogIn());
                }
                if (!ImgRock.LoggedIn && flag.HasFlag(LoginFlag.ImgRock))
                {
                    loginTasks.Add(ImgRock.LogIn());
                }
                if (!PixSense.LoggedIn && flag.HasFlag(LoginFlag.PixSense))
                {
                    loginTasks.Add(PixSense.LogIn());
                }

                Task <bool> megaLoginTask = null;
                if (!MegaLoggedIn && flag.HasFlag(LoginFlag.MEGA))
                {
                    megaLoginTask = MEGA.LogIn();
                    loginTasks.Add(megaLoginTask);
                }

                Task <bool> rapidgatorLoginTask = null;
                if (!RapidgatorLoggedIn && flag.HasFlag(LoginFlag.Rapidgator))
                {
                    rapidgatorLoginTask = Rapidgator.LogIn();
                    loginTasks.Add(rapidgatorLoginTask);
                }

                Task <bool> uploadGIGLoginTask = null;
                if (!UploadGIGLoggedIn && flag.HasFlag(LoginFlag.UploadGIG))
                {
                    uploadGIGLoginTask = UploadGIG.LogIn();
                    loginTasks.Add(uploadGIGLoginTask);
                }

                if (!Zippyshare.LoggedIn && flag.HasFlag(LoginFlag.Zippyshare))
                {
                    loginTasks.Add(Zippyshare.LogIn());
                }


                Task <bool> blogLoginTask = null;
                if (!BloggerLoggedIn && flag.HasFlag(LoginFlag.Blogger))
                {
                    blogLoginTask = Blogger.LogIn();
                    loginTasks.Add(blogLoginTask);
                }

                await Task.WhenAll(loginTasks);

                if (megaLoginTask != null)
                {
                    MegaLoggedIn = await megaLoginTask;
                }
                if (rapidgatorLoginTask != null)
                {
                    RapidgatorLoggedIn = await rapidgatorLoginTask;
                }
                if (uploadGIGLoginTask != null)
                {
                    UploadGIGLoggedIn = await uploadGIGLoginTask;
                }
                if (blogLoginTask != null)
                {
                    BloggerLoggedIn = await blogLoginTask;
                }
            }
            catch (Exception ex)
            {
                Message = ex.Message;
                Logger.ErrorException(ex.Message, ex);
            }

            Message = "Login done";

            var ret = true;

            if (flag.HasFlag(LoginFlag.ImgChili))
            {
                ret &= ImgChili.LoggedIn;
            }
            if (flag.HasFlag(LoginFlag.ImgRock))
            {
                ret &= ImgRock.LoggedIn;
            }
            if (flag.HasFlag(LoginFlag.PixSense))
            {
                ret &= PixSense.LoggedIn;
            }
            if (flag.HasFlag(LoginFlag.MEGA))
            {
                ret &= MegaLoggedIn;
            }
            if (flag.HasFlag(LoginFlag.Rapidgator))
            {
                ret &= RapidgatorLoggedIn;
            }
            if (flag.HasFlag(LoginFlag.UploadGIG))
            {
                ret &= UploadGIGLoggedIn;
            }
            if (flag.HasFlag(LoginFlag.Zippyshare))
            {
                ret &= Zippyshare.LoggedIn;
            }
            if (flag.HasFlag(LoginFlag.Blogger))
            {
                ret &= BloggerLoggedIn;
            }
            CanUpload = ret;
            return(ret);
        }