private static List<DanbooruTag> RemoveIgnoredTags(DanbooruFilenameFormat format, List<DanbooruTag> groupedTags) { foreach (DanbooruTag ignoredTag in format.IgnoredTags) { if (format.IgnoreTagsUseRegex) { if (!String.IsNullOrWhiteSpace(format.IgnoredTagsRegex)) { Regex re = new Regex(format.IgnoredTagsRegex, RegexOptions.IgnoreCase); if (format.IgnoredTagsOnlyForGeneral) { groupedTags.RemoveAll(x => x.Type == DanbooruTagType.General && re.IsMatch(x.Name)); } else { groupedTags.RemoveAll(x => re.IsMatch(x.Name)); } } } else { groupedTags.RemoveAll(x => x.Name == ignoredTag.Name); } } return groupedTags; }
/// <summary> /// For constructing TAGS_FILENAME. /// </summary> /// <param name="baseFolder"></param> /// <param name="format"></param> /// <param name="post"></param> /// <param name="limit"></param> /// <returns></returns> public static string MakeFilename(DanbooruFilenameFormat format, DanbooruPost post) { string filename = format.FilenameFormat; string provider = post.Provider.Name; string query = post.Query; string searchTags = post.SearchTags; string originalFileName = post.FileUrl.Split('/').Last(); // sanitizing the format filename = Helper.SanitizeFilename(filename, true); //remove extension originalFileName = originalFileName.Substring(0, originalFileName.LastIndexOf('.')); originalFileName = Uri.UnescapeDataString(originalFileName); filename = filename.Replace("%provider%", Helper.SanitizeFilename(provider)); filename = filename.Replace("%id%", post.Id); filename = filename.Replace("%rating%", post.Rating); filename = filename.Replace("%md5%", post.MD5); filename = filename.Replace("%searchParam%", Helper.SanitizeFilename(query)); filename = filename.Replace("%searchtag%", Helper.SanitizeFilename(searchTags)); filename = filename.Replace("%originalFilename%", Helper.SanitizeFilename(originalFileName)); string dtFormat = Properties.Settings.Default.DateTimeFormat; if (String.IsNullOrWhiteSpace(dtFormat)) dtFormat = "yyyy-mm-dd HH:mm:ss"; filename = filename.Replace("%uploadDateTime%", Helper.SanitizeFilename(post.CreatedAtDateTime.ToString(dtFormat))); // copy the tags entity to be grouped. var groupedTags = post.TagsEntity; // custom sort to prioritize some tags based on file definition // Issue #46 and #81 // regex support if (File.Exists(PRIORITY_TAGS)) { var priorityTags = ReadTagsFromTextFile(PRIORITY_TAGS); groupedTags.Sort((a, b) => { var containA = priorityTags.Exists(x => Regex.IsMatch(a.Name, x.Name)); var containB = priorityTags.Exists(x => Regex.IsMatch(b.Name, x.Name)); if (containA && !containB) return -1; if (!containA && containB) return 1; else return a.CompareTo(b); }); } else { groupedTags.Sort(); } // remove ignored tags groupedTags = RemoveIgnoredTags(format, groupedTags); // artist var artist = FilterTags(post, groupedTags, DanbooruTagType.Artist, format.ArtistGroupLimit, format.ArtistGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var artistStr = Helper.SanitizeFilename(artist).Trim(); filename = filename.Replace("%artist%", artistStr); // copyright var copyright = FilterTags(post, groupedTags, DanbooruTagType.Copyright, format.CopyrightGroupLimit, format.CopyrightGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var copyStr = Helper.SanitizeFilename(copyright.Trim()); filename = filename.Replace("%copyright%", copyStr); // character var character = FilterTags(post, groupedTags, DanbooruTagType.Character, format.CharacterGroupLimit, format.CharacterGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var charaStr = Helper.SanitizeFilename(character.Trim()); filename = filename.Replace("%character%", charaStr); // cirle var circle = FilterTags(post, groupedTags, DanbooruTagType.Circle, format.CircleGroupLimit, format.CircleGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var circleStr = Helper.SanitizeFilename(circle.Trim()); filename = filename.Replace("%circle%", circleStr); // faults var faults = FilterTags(post, groupedTags, DanbooruTagType.Faults, format.FaultsGroupLimit, format.FaultsGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var faultStr = Helper.SanitizeFilename(faults.Trim()); filename = filename.Replace("%faults%", faultStr); // general var general = FilterTags(post, groupedTags, DanbooruTagType.General, 0, "", "", format.IsReplaceMode, format.TagReplaceUnderscoreToSpace); var generalStr = Helper.SanitizeFilename(general.Trim()); filename = filename.Replace("%general%", generalStr); // all tags var allTempTags = groupedTags.Select(x => x.Name).ToList(); if (format.TagReplaceUnderscoreToSpace) { for (int i = 0; i < allTempTags.Count; i++) { allTempTags[i] = allTempTags[i].Replace("_", " ").Trim(); } } filename = filename.Replace("%tags%", Helper.SanitizeFilename(string.Join(" ", allTempTags))); // append base folder from Save Folder text box if (format.BaseFolder.EndsWith(@"\")) filename = format.BaseFolder + filename; else if (!String.IsNullOrWhiteSpace(format.BaseFolder)) filename = format.BaseFolder + @"\" + filename; filename = filename.Substring(0, filename.Length < format.Limit ? filename.Length : format.Limit).Trim(); return filename; }
/// <summary> /// For constructing TAGS_FILENAME. /// </summary> /// <param name="baseFolder"></param> /// <param name="format"></param> /// <param name="post"></param> /// <param name="limit"></param> /// <returns></returns> public static string MakeFilename(DanbooruFilenameFormat format, DanbooruPost post) { string filename = format.FilenameFormat; string provider = post.Provider.Name; string query = post.Query; string searchTags = post.SearchTags; string originalFileName = post.FileUrl.Split('/').Last(); // sanitizing the format filename = Helper.SanitizeFilename(filename, true); //remove extension originalFileName = originalFileName.Substring(0, originalFileName.LastIndexOf('.')); originalFileName = Uri.UnescapeDataString(originalFileName); filename = filename.Replace("%provider%", Helper.SanitizeFilename(provider)); filename = filename.Replace("%id%", post.Id); filename = filename.Replace("%rating%", post.Rating); filename = filename.Replace("%md5%", post.MD5); filename = filename.Replace("%searchParam%", Helper.SanitizeFilename(query)); filename = filename.Replace("%searchtag%", Helper.SanitizeFilename(searchTags)); filename = filename.Replace("%originalFilename%", Helper.SanitizeFilename(originalFileName)); // copy the tags entity to be grouped. var groupedTags = post.TagsEntity; groupedTags.Sort(); // remove ignored tags groupedTags = RemoveIgnoredTags(format, groupedTags); // artist var artist = FilterTags(post, groupedTags, DanbooruTagType.Artist, format.ArtistGroupLimit, format.ArtistGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode); var artistStr = Helper.SanitizeFilename(artist).Trim(); if (String.IsNullOrEmpty(artistStr)) artistStr = DanbooruDownloader3.Properties.Settings.Default.tagNoArtistValue; filename = filename.Replace("%artist%", artistStr); // copyright var copyright = FilterTags(post, groupedTags, DanbooruTagType.Copyright, format.CopyrightGroupLimit, format.CopyrightGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode); var copyStr = Helper.SanitizeFilename(copyright.Trim()); if (String.IsNullOrEmpty(copyStr)) copyStr = DanbooruDownloader3.Properties.Settings.Default.tagNoCopyrightValue; filename = filename.Replace("%copyright%", copyStr); // character var character = FilterTags(post, groupedTags, DanbooruTagType.Character, format.CharacterGroupLimit, format.CharacterGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode); var charaStr = Helper.SanitizeFilename(character.Trim()); if (String.IsNullOrEmpty(charaStr)) charaStr = DanbooruDownloader3.Properties.Settings.Default.tagNoCharaValue; filename = filename.Replace("%character%", charaStr); // cirle var circleSelection = post.TagsEntity.Where<DanbooruTag>(x => x.Type == DanbooruTagType.Circle).Select(x => x.Name); var circle = FilterTags(post, groupedTags, DanbooruTagType.Circle, format.CircleGroupLimit, format.CircleGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode); var circleStr = Helper.SanitizeFilename(circle.Trim()); if (String.IsNullOrEmpty(circleStr)) circleStr = DanbooruDownloader3.Properties.Settings.Default.tagNoCircleValue; filename = filename.Replace("%circle%", circleStr); // faults var faultsSelection = post.TagsEntity.Where<DanbooruTag>(x => x.Type == DanbooruTagType.Faults).Select(x => x.Name); var faults = FilterTags(post, groupedTags, DanbooruTagType.Faults, format.FaultsGroupLimit, format.FaultsGroupReplacement, format.MissingTagReplacement, format.IsReplaceMode); var faultStr = Helper.SanitizeFilename(faults.Trim()); if (String.IsNullOrEmpty(faultStr)) faultStr = DanbooruDownloader3.Properties.Settings.Default.tagNoFaultValue; filename = filename.Replace("%faults%", faultStr); // all tags filename = filename.Replace("%tags%", Helper.SanitizeFilename(string.Join(" ", groupedTags.Select(x => x.Name)))); // append base folder from Save Folder text box if (format.BaseFolder.EndsWith(@"\")) filename = format.BaseFolder + filename; else if (!String.IsNullOrWhiteSpace(format.BaseFolder)) filename = format.BaseFolder + @"\" + filename; filename = filename.Substring(0, filename.Length < format.Limit ? filename.Length : format.Limit).Trim(); // check if contains subdirectory if (filename.Contains(@"\")) { string dir = filename.Substring(0, filename.LastIndexOf(@"\")); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); } return filename; }
public void DoBatchJob(BindingList<DanbooruBatchJob> batchJob) { ToggleBatchJobButtonDelegate bjd = new ToggleBatchJobButtonDelegate(ToggleBatchJobButton); UpdateUiDelegate del = new UpdateUiDelegate(UpdateUi); UpdateUiDelegate2 del2 = new UpdateUiDelegate2(UpdateUi); ExtendedWebClient _clientPost = new ExtendedWebClient(); if (batchJob != null) { UpdateStatus2("Starting Batch Job"); for (int i = 0; i < batchJob.Count; i++) { batchJob[i].CurrentPage = 0; if (!batchJob[i].isCompleted) { UpdateLog("DoBatchJob", "Processing Batch Job#" + i); DanbooruPostDao prevDao = null; bool flag = true; int currPage = 0; int postCount = 0; do { // stop/pause event handling outside _pauseEvent.WaitOne(Timeout.Infinite); if (_shutdownEvent.WaitOne(0)) { batchJob[i].Status = " ==> Stopped."; // toggle button BeginInvoke(bjd, new object[] { true }); UpdateLog("DoBatchJob", "Batch Job Stopped."); UpdateStatus2("Batch Job Stopped."); return; } DanbooruPostDao d = null; int imgCount = 0; int skipCount = 0; string url; string query = ""; #region Construct the searchParam if (batchJob[i].Provider.BoardType == BoardType.Danbooru || batchJob[i].Provider.BoardType == BoardType.Shimmie2) { currPage = batchJob[i].CurrentPage; } else if (batchJob[i].Provider.BoardType == BoardType.Gelbooru) { if (batchJob[i].Provider.Preferred == PreferredMethod.Html) { currPage = batchJob[i].CurrentPage * postCount; } else { currPage = batchJob[i].CurrentPage; } } DanbooruSearchParam searchParam = GetSearchParamsFromJob(batchJob[i], currPage); url = batchJob[i].Provider.GetQueryUrl(searchParam); #endregion Construct the searchParam try { #region Get and load the image list batchJob[i].Status = "Getting list for page: " + searchParam.Page; BeginInvoke(del); UpdateLog("DoBatchJob", "Downloading list: " + url); d = GetBatchImageList(url, query, batchJob[i]); if (d == null) { // Cannot get list. UpdateLog("DoBatchJob", "Cannot load list"); batchJob[i].Status = "Cannot load list."; batchJob[i].isCompleted = false; batchJob[i].isError = true; flag = false; } else if (d.Posts == null || d.Posts.Count == 0) { // No more image UpdateLog("DoBatchJob", "No more image."); batchJob[i].Status = "No more image."; flag = false; //break; } else { if (prevDao != null) { // identical data returned, probably no more new image. if (prevDao.RawData != null && prevDao.RawData.Equals(d.RawData)) { UpdateLog("DoBatchJob", "Identical list, probably last page."); batchJob[i].Status = "Identical list, probably last page."; flag = false; //break; } } prevDao = d; batchJob[i].Total = d.PostCount; batchJob[i].CurrentPageTotal = d.Posts.Count; batchJob[i].CurrentPageOffset = d.Offset; #endregion Get and load the image list postCount = d.Posts.Count; foreach (DanbooruPost post in d.Posts) { // Update progress bar object[] myArray = new object[2]; myArray[0] = batchJob[i].ProcessedTotal; myArray[1] = d.PostCount < batchJob[i].Limit ? d.PostCount : batchJob[i].Limit; BeginInvoke(del2, myArray); // thread handling _pauseEvent.WaitOne(Timeout.Infinite); if (_shutdownEvent.WaitOne(0)) { batchJob[i].Status = " ==> Stopped."; // toggle button BeginInvoke(bjd, new object[] { true }); UpdateLog("DoBatchJob", "Batch Job Stopped."); UpdateStatus2("Batch Job Stopped."); return; } // check if have url and post is not deleted if (string.IsNullOrWhiteSpace(post.FileUrl) && (post.Status != "deleted" || chkProcessDeletedPost.Checked)) { ResolveFileUrlBatch(_clientPost, post); } //Choose the correct urls var targetUrl = post.FileUrl; if (_ImageSize == "Thumb" && !String.IsNullOrWhiteSpace(post.PreviewUrl)) { targetUrl = post.PreviewUrl; } else if (_ImageSize == "Jpeg" && !String.IsNullOrWhiteSpace(post.JpegUrl)) { targetUrl = post.JpegUrl; } else if (_ImageSize == "Sample" && !String.IsNullOrWhiteSpace(post.SampleUrl)) { targetUrl = post.SampleUrl; } batchJob[i].Status = "Downloading: " + targetUrl; BeginInvoke(del); //if (post.Provider == null) post.Provider = cbxProvider.Text; //if (post.Query == null) post.Query = txtQuery.Text; //if (post.SearchTags == null) post.SearchTags = txtTags.Text; bool download = true; // check if blacklisted if (download && post.Hidden) { ++skipCount; ++batchJob[i].Skipped; download = false; UpdateLog("DoBatchJob", "Download skipped, contains blacklisted tag: " + post.Tags + " Url: " + targetUrl); } string filename = ""; if (download && !string.IsNullOrWhiteSpace(targetUrl)) { var format = new DanbooruFilenameFormat() { FilenameFormat = batchJob[i].SaveFolder, Limit = Convert.ToInt32(txtFilenameLength.Text), BaseFolder = txtSaveFolder.Text, MissingTagReplacement = txtTagReplacement.Text, ArtistGroupLimit = Convert.ToInt32(txtArtistTagGrouping.Text), CharacterGroupLimit = Convert.ToInt32(txtCharaTagGrouping.Text), CopyrightGroupLimit = Convert.ToInt32(txtCopyTagGrouping.Text), CircleGroupLimit = Convert.ToInt32(txtCircleTagGrouping.Text), FaultsGroupLimit = Convert.ToInt32(txtFaultsTagGrouping.Text), IgnoredTags = DanbooruTagsDao.Instance.ParseTagsString(txtIgnoredTags.Text.Replace(Environment.NewLine, " ")), IgnoredTagsRegex = txtIgnoredTags.Text.Trim().Replace(Environment.NewLine, "|"), IgnoreTagsUseRegex = chkIgnoreTagsUseRegex.Checked, IsReplaceMode = chkReplaceMode.Checked, IgnoredTagsOnlyForGeneral = chkIgnoreForGeneralTag.Checked, TagReplaceUnderscoreToSpace = chkIsReplaceUnderscoreTag.Checked }; string extension = Helper.getFileExtensions(targetUrl); filename = Helper.MakeFilename(format, post) + extension; } // check if exist if (download && !chkOverwrite.Checked) { if (File.Exists(filename)) { ++skipCount; ++batchJob[i].Skipped; download = false; UpdateLog("DoBatchJob", "Download skipped, file exists: " + filename); } } if (download && String.IsNullOrWhiteSpace(targetUrl)) { ++skipCount; ++batchJob[i].Skipped; download = false; UpdateLog("DoBatchJob", "Download skipped, ID: " + post.Id + " No file_url, probably deleted"); } Uri uri = null; if (download && !Uri.TryCreate(targetUrl, UriKind.RelativeOrAbsolute, out uri)) { ++skipCount; ++batchJob[i].Skipped; download = false; UpdateLog("DoBatchJob", "Download skipped, ID: " + post.Id + " Invalid URL: " + targetUrl); } #region download if (download) { imgCount = DoDownloadBatch(targetUrl, batchJob[i], post, filename); } #endregion download // check if more than available post if (batchJob[i].ProcessedTotal >= d.PostCount && d.PostCount != 0) { UpdateLog("DoBatchJob", "No more post."); flag = false; break; } // check if over given limit if (batchJob[i].ProcessedTotal >= batchJob[i].Limit) { UpdateLog("DoBatchJob", "Limit Reached."); flag = false; break; } // check batch job delay int delay = 0; Int32.TryParse(Properties.Settings.Default.BatchJobDelay, out delay); if ((Properties.Settings.Default.DelayIncludeSkipped || download) && delay > 0) { UpdateLog("DoBatchJob", String.Format("Waiting for {0}ms for the next post.", delay)); Thread.Sleep(delay); } } } batchJob[i].Status = " ==> Done."; } catch (Exception ex) { string message = ex.Message; string responseMessage = ""; if (ex.InnerException != null) { message += Environment.NewLine + "Inner: " + ex.InnerException.Message; } message += Environment.NewLine + "Stack Trace: " + Environment.NewLine + ex.StackTrace; message += Environment.NewLine + "Query: " + batchJob[i].TagQuery; batchJob[i].isError = true; batchJob[i].isCompleted = false; if (ex.GetType() == typeof(System.Net.WebException)) { System.Net.WebException wex = (System.Net.WebException)ex; if (wex.Status == WebExceptionStatus.ProtocolError && wex.Response.Headers.AllKeys.Contains("Status") && wex.Response.Headers["Status"].ToString() == "500") { using (var response = wex.Response.GetResponseStream()) { if (response != null) { var option = new DanbooruPostDaoOption() { Provider = _currProvider, Query = query, SearchTags = batchJob[i].TagQuery, Url = url, Referer = "", BlacklistedTags = TagBlacklist, BlacklistedTagsRegex = TagBlacklistRegex, BlacklistedTagsUseRegex = chkBlacklistTagsUseRegex.Checked, IgnoredTags = TagIgnore, IgnoredTagsRegex = TagIgnoreRegex, IgnoredTagsUseRegex = chkIgnoreTagsUseRegex.Checked, IsBlacklistOnlyForGeneral = chkBlacklistOnlyGeneral.Checked }; var resp = new DanbooruPostDao(response, option); responseMessage = resp.ResponseMessage; flag = false; } } } } if (ex.Message.Contains("(400)") || ex.Message.Contains("(403)") || ex.Message.Contains("(500)") || ex.Message.Contains("resolved")) { flag = false; } batchJob[i].Status = " ==> Error: " + (string.IsNullOrWhiteSpace(responseMessage) ? ex.Message : responseMessage) + Environment.NewLine; if (!string.IsNullOrWhiteSpace(responseMessage)) UpdateLog("DoBatchJob", "Server Message: " + responseMessage, ex); else UpdateLog("DoBatchJob", "Error: " + message, ex); if (cbxAbortOnError.Checked) { MessageBox.Show(message, "Batch Download"); break; } } finally { BeginInvoke(del); { // Update progress bar object[] myArray = new object[2]; myArray[0] = batchJob[i].ProcessedTotal; if (d != null) { myArray[1] = d.PostCount < batchJob[i].Limit ? d.PostCount : batchJob[i].Limit; } else { myArray[1] = -1; } BeginInvoke(del2, myArray); } } ++batchJob[i].CurrentPage; } while (flag); UpdateLog("DoBatchJob", "Batch Job #" + i + ": Done"); if (batchJob[i].isError) { batchJob[i].isCompleted = false; } else { batchJob[i].isCompleted = true; } BeginInvoke(del); } } } BeginInvoke(bjd, new object[] { true }); UpdateStatus2("Batch Job Completed!", true); { // hide progress bar object[] myArray = new object[2]; myArray[0] = -1; myArray[1] = -1; BeginInvoke(del2, myArray); } }
private string MakeCompleteFilename(DanbooruPost post, string url) { var format = new DanbooruFilenameFormat() { FilenameFormat = txtFilenameFormat.Text, Limit = Convert.ToInt32(txtFilenameLength.Text), BaseFolder = txtSaveFolder.Text, MissingTagReplacement = txtTagReplacement.Text, ArtistGroupLimit = Convert.ToInt32(txtArtistTagGrouping.Text), CharacterGroupLimit = Convert.ToInt32(txtCharaTagGrouping.Text), CopyrightGroupLimit = Convert.ToInt32(txtCopyTagGrouping.Text), CircleGroupLimit = Convert.ToInt32(txtCircleTagGrouping.Text), FaultsGroupLimit = Convert.ToInt32(txtFaultsTagGrouping.Text), IgnoredTags = DanbooruTagsDao.Instance.ParseTagsString(txtIgnoredTags.Text.Replace(Environment.NewLine, " ")), IgnoredTagsRegex = txtIgnoredTags.Text.Trim().Replace(Environment.NewLine, "|"), IgnoreTagsUseRegex = chkIgnoreTagsUseRegex.Checked, IsReplaceMode = chkReplaceMode.Checked, IgnoredTagsOnlyForGeneral = chkIgnoreForGeneralTag.Checked, TagReplaceUnderscoreToSpace = chkIsReplaceUnderscoreTag.Checked }; string extension = Helper.getFileExtensions(url); string filename = Helper.MakeFilename(format, post) + extension; return filename; }
/// <summary> /// Async, will be called from event handler client file download. /// </summary> /// <param name="i"> downloadList index</param> public void DownloadRows(DataGridViewRow row) { if (_isCanceled) return; if (CheckDownloadGrid()) { _isDownloading = true; // Update the progress bar tsProgress2.Visible = true; tsProgress2.Maximum = row.DataGridView.Rows.Count; tsProgress2.Value = row.Index > tsProgress2.Maximum ? tsProgress2.Maximum : row.Index + 1; tsProgressBar.Style = ProgressBarStyle.Continuous; if (_isPaused) { DialogResult result = MessageBox.Show("Paused." + Environment.NewLine + "Click OK to continue.", "Download", MessageBoxButtons.OKCancel); _isPaused = false; btnPauseDownload.Enabled = true; if (result.Equals(DialogResult.Cancel)) { EnableDownloadControls(true); tsStatus.Text = "Canceled."; _isDownloading = false; return; } } tsStatus.Text = "Downloading Post #" + row.Index; DanbooruPost post = _downloadList[row.Index]; if (!post.Completed) { row.Selected = true; if (chkAutoFocus.Checked) dgvDownload.FirstDisplayedScrollingRowIndex = row.Index; string url = (string)row.Cells["colUrl2"].Value; Uri uri = null; if (string.IsNullOrWhiteSpace(url)) { ResolveFileUrl(post); } if (url == Constants.LOADING_URL) { // still loading post url row.Cells["colProgress2"].Value = "Still loading post url, try again later."; UpdateLog("[DownloadRow]", "Still loading post url, try again later.: " + row.Index); } else if (url == Constants.NO_POST_PARSER) { // no parser post url row.Cells["colProgress2"].Value = "No post parser for provider: " + post.Provider; UpdateLog("[DownloadRow]", "No post parser for provider: " + post.Provider + " at : " + row.Index); } else if (post.Status == "deleted" && !chkProcessDeletedPost.Checked) { row.Cells["colProgress2"].Value = "Post is deleted."; UpdateLog("[DownloadRow]", "Post is deleted for row: " + row.Index); } else if (!string.IsNullOrWhiteSpace(url) && Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) // check if post active and url valid { if (post.Provider == null) post.Provider = _listProvider[cbxProvider.SelectedIndex]; if (post.Query == null) post.Query = txtQuery.Text; if (post.SearchTags == null) post.SearchTags = txtTags.Text; var format = new DanbooruFilenameFormat() { FilenameFormat = txtFilenameFormat.Text, Limit = Convert.ToInt32(txtFilenameLength.Text), BaseFolder = txtSaveFolder.Text, MissingTagReplacement = txtTagReplacement.Text, ArtistGroupLimit = Convert.ToInt32(txtArtistTagGrouping.Text), CharacterGroupLimit = Convert.ToInt32(txtCharaTagGrouping.Text), CopyrightGroupLimit = Convert.ToInt32(txtCopyTagGrouping.Text), CircleGroupLimit = Convert.ToInt32(txtCircleTagGrouping.Text), FaultsGroupLimit = Convert.ToInt32(txtFaultsTagGrouping.Text), IgnoredTags = DanbooruTagsDao.Instance.ParseTagsString(txtIgnoredTags.Text.Replace(Environment.NewLine, " ")), IgnoredTagsRegex = txtIgnoredTags.Text.Trim().Replace(Environment.NewLine, "|"), IgnoreTagsUseRegex = chkIgnoreTagsUseRegex.Checked, IsReplaceMode = chkReplaceMode.Checked, IgnoredTagsOnlyForGeneral = chkIgnoreForGeneralTag.Checked }; string extension = Helper.getFileExtensions(url); string filename = Helper.MakeFilename(format, post) + extension; if (chkOverwrite.Checked || !File.Exists(filename)) { string dir = filename.Substring(0, filename.LastIndexOf(@"\")); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); row.Cells["colFilename"].Value = filename; var filename2 = filename + ".!tmp"; if (File.Exists(filename2)) { row.Cells["colProgress2"].Value = "Deleting temporary file: " + filename2; File.Delete(filename2); } // the actual download _clientFile.Referer = post.Referer; Program.Logger.Info("[DownloadRow] Downloading " + url); Program.Logger.Info("[DownloadRow] Saved to " + filename); row.Cells["colDownloadStart2"].Value = DateTime.Now; _clientFile.DownloadFileAsync(uri, filename2, row); txtLog.AppendText("[clientFileDownload] Saving to " + filename2 + Environment.NewLine); return; } else { // File exist and overwrite is no checked. row.Cells["colProgress2"].Value = "File exists!"; UpdateLog("[DownloadRow]", "File exists: " + filename); } } else { // no valid url row.Cells["colProgress2"].Value = "No valid file_url, probably deleted."; UpdateLog("[DownloadRow]", "No valid file_url for row: " + row.Index); } } // proceed with the next row if (row.Index < dgvDownload.Rows.GetLastRow(DataGridViewElementStates.None)) { DownloadRows(dgvDownload.Rows[row.Index + 1]); } else { // no more row _isPaused = false; _isDownloading = false; ShowMessage("Download List", "Download Complete!"); EnableDownloadControls(true); tsProgress2.Visible = false; } } }