protected override void NotifyIndexerOfObfuscatedUpload(UploadEntry upload) { if (upload.UploadedAt != null) { String notificationUrl = String.Format(Configuration.ObfuscatedNotificationUrl); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; Byte[] nzbFileArray = UTF8Encoding.Default.GetBytes(upload.NzbContents); HttpClient httpClient = new HttpClient(); MultipartFormDataContent form = new MultipartFormDataContent(); form.Add(new ByteArrayContent(nzbFileArray), "file", upload.CleanedName + ".nzb"); HttpResponseMessage response = httpClient.PostAsync(notificationUrl, form).Result; HttpContent content = response.Content; String contentString = content.ReadAsStringAsync().Result; if (response.StatusCode != HttpStatusCode.OK) { throw new Exception("Error when notifying indexer: " + response.StatusCode + " " + response.ReasonPhrase + " " + contentString); } } }
private void HandleServerError(UploadEntry upload, String responseBody) { if (responseBody.IndexOf("ALREADY EXISTS") >= 0) { log.InfoFormat("The release {0} already exists.", upload.CleanedName); if (upload.IsRepost) { log.WarnFormat("This release was already a repost. Cancelling."); upload.Cancelled = true; upload.Move(Configuration, Location.Failed); } else { WatchFolderSettings wfConfig = Configuration.GetWatchFolderSettings(upload.WatchFolderShortName); upload.CleanedName = upload.CleanedName.Remove(upload.CleanedName.Length - wfConfig.PostTag.Length - 1) + "-REPOST" + wfConfig.PostTag; upload.IsRepost = true; log.InfoFormat("Reuploading as {0}", upload.CleanedName); upload.UploadedAt = null; upload.Move(Configuration, Location.Queue); } } else { log.WarnFormat("Fatal exception on the server side: {0}", responseBody); log.InfoFormat("Reposting {0}", upload.CleanedName); upload.UploadedAt = null; upload.Move(Configuration, Location.Queue); } DBHandler.Instance.UpdateUploadEntry(upload); }
public UploadEntry GetNextUploadEntryToUpload() { lock (lockObject) using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteCommand cmd = conn.CreateCommand()) { cmd.CommandText = @"SELECT ROWID, * from UploadEntries WHERE UploadedAt IS NULL AND Cancelled = 0 ORDER BY PriorityNum DESC, CreatedAt ASC LIMIT 1"; using (SqliteDataReader reader = cmd.ExecuteReader()) { UploadEntry uploadEntry = null; if (reader.Read()) { uploadEntry = GetUploadEntryFromReader(reader); } return(uploadEntry); } } } }
public UploadEntry GetActiveUploadEntry(String name) { lock (lockObject) using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteCommand cmd = conn.CreateCommand()) { cmd.CommandText = @"SELECT ROWID, * from UploadEntries WHERE Name = @name AND Cancelled = 0"; cmd.Parameters.Add(new SqliteParameter("@name", name)); using (SqliteDataReader reader = cmd.ExecuteReader()) { UploadEntry uploadEntry = null; if (reader.Read()) { uploadEntry = GetUploadEntryFromReader(reader); if (reader.Read()) { throw new Exception("Got more than one result matching this name. The database is not consistent."); } } return(uploadEntry); } } } }
private static UploadEntry GetUploadEntryFromReader(SqliteDataReader reader) { UploadEntry uploadEntry = new UploadEntry(); uploadEntry.ID = (Int64)reader["ROWID"]; uploadEntry.Name = reader["Name"] as String; uploadEntry.Size = (Int64)reader["Size"]; uploadEntry.CleanedName = reader["CleanedName"] as String; uploadEntry.ObscuredName = reader["ObscuredName"] as String; uploadEntry.RemoveAfterVerify = GetBoolean(reader["RemoveAfterVerify"]); uploadEntry.CreatedAt = GetDateTime(reader["CreatedAt"]); uploadEntry.UploadedAt = GetNullableDateTime(reader["UploadedAt"]); uploadEntry.NotifiedIndexerAt = GetNullableDateTime(reader["NotifiedIndexerAt"]); uploadEntry.SeenOnIndexAt = GetNullableDateTime(reader["SeenOnIndexerAt"]); uploadEntry.Cancelled = GetBoolean(reader["Cancelled"]); uploadEntry.WatchFolderShortName = reader["WatchFolderShortName"] as String; uploadEntry.UploadAttempts = (Int64)reader["UploadAttempts"]; uploadEntry.RarPassword = reader["RarPassword"] as String; uploadEntry.PriorityNum = (Int64)reader["PriorityNum"]; uploadEntry.NzbContents = reader["NzbContents"] as String; uploadEntry.IsRepost = GetBoolean(reader["IsRepost"]); uploadEntry.NotificationCount = (Int64)reader["NotificationCount"]; uploadEntry.CurrentLocation = GetLocation(reader["CurrentLocation"]); return(uploadEntry); }
private static UploadEntry GetUploadEntryFromReader(SqliteDataReader reader) { #pragma warning disable IDE0017 // Simplify object initialization UploadEntry uploadEntry = new UploadEntry(); #pragma warning restore IDE0017 // Simplify object initialization uploadEntry.ID = (Int64)reader["RowIDAlias"]; uploadEntry.Name = reader["Name"] as String; uploadEntry.Size = (Int64)reader["Size"]; uploadEntry.CleanedName = reader["CleanedName"] as String; uploadEntry.ObscuredName = reader["ObscuredName"] as String; uploadEntry.RemoveAfterVerify = GetBoolean(reader["RemoveAfterVerify"]); uploadEntry.CreatedAt = GetDateTime(reader["CreatedAt"]); uploadEntry.UploadedAt = GetNullableDateTime(reader["UploadedAt"]); uploadEntry.NotifiedIndexerAt = GetNullableDateTime(reader["NotifiedIndexerAt"]); uploadEntry.SeenOnIndexAt = GetNullableDateTime(reader["SeenOnIndexerAt"]); uploadEntry.Cancelled = GetBoolean(reader["Cancelled"]); uploadEntry.WatchFolderShortName = reader["WatchFolderShortName"] as String; uploadEntry.UploadAttempts = (Int64)reader["UploadAttempts"]; uploadEntry.RarPassword = reader["RarPassword"] as String; uploadEntry.PriorityNum = (Int64)reader["PriorityNum"]; uploadEntry.NzbContents = reader["NzbContents"] as String; uploadEntry.IsRepost = GetBoolean(reader["IsRepost"]); uploadEntry.NotificationCount = (Int64)reader["NotificationCount"]; uploadEntry.CurrentLocation = GetLocation(reader["CurrentLocation"]); uploadEntry.HasNfo = GetBoolean(reader["HasNfo"]); return(uploadEntry); }
private void NotifyIndexerOfObfuscatedUpload(UploadEntry upload) { String notificationGetUrl = String.Format( configuration.ObfuscatedNotificationUrl, Uri.EscapeDataString(upload.ObscuredName), Uri.EscapeDataString(upload.CleanedName)); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; HttpWebRequest request = WebRequest.Create(notificationGetUrl) as HttpWebRequest; //Mono does not support CreateHttp //request.ServerCertificateValidationCallback = ServerCertificateValidationCallback; //Not implemented in mono request.Method = "GET"; request.Timeout = 60 * 1000; HttpWebResponse response = request.GetResponse() as HttpWebResponse; if (response.StatusCode != HttpStatusCode.OK) { throw new Exception("Error when notifying indexer: " + response.StatusCode + " " + response.StatusDescription); } using (var reader = new StreamReader(response.GetResponseStream())) { var responseBody = reader.ReadToEnd(); if (responseBody.IndexOf("<error code=") >= 0) { throw new Exception("Error when notifying indexer: " + responseBody); } } }
public void AddNewUploadEntry(UploadEntry uploadentry) { using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteTransaction trans = conn.BeginTransaction()) { using (SqliteCommand cmd = conn.CreateCommand()) { cmd.Transaction = trans; cmd.CommandText = @"UPDATE UploadEntries SET Cancelled = 1 WHERE Name = @name"; cmd.Parameters.Add(new SqliteParameter("@name", uploadentry.Name)); cmd.ExecuteNonQuery(); //TODO: log here how many other entries were cancelled. cmd.CommandText = @"INSERT INTO UploadEntries( Name, Size, CleanedName, ObscuredName, RemoveAfterVerify, CreatedAt, UploadedAt, NotifiedIndexerAt, SeenOnIndexerAt, Cancelled) VALUES( @name, @size, @cleanedName, @ObscuredName, @removeAfterVerify, @createdAt, @uploadedAt, @notifiedIndexerAt, @seenOnIndexerAt, @cancelled)"; cmd.Parameters.Add(new SqliteParameter("@name", uploadentry.Name)); cmd.Parameters.Add(new SqliteParameter("@size", uploadentry.Size)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadentry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadentry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadentry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@createdAt", GetDbValue(uploadentry.CreatedAt))); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadentry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadentry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadentry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadentry.Cancelled))); cmd.ExecuteNonQuery(); cmd.CommandText = "select last_insert_rowid()"; cmd.Parameters.Clear(); uploadentry.ID = (Int64)cmd.ExecuteScalar(); } trans.Commit(); } } }
private Boolean UploadIsOnIndexer(UploadEntry upload) { var postAge = (Int32)Math.Ceiling((DateTime.UtcNow - upload.UploadedAt.Value).TotalDays + 1); String searchName = GetIndexerSearchName(upload.CleanedName); String verificationGetUrl = String.Format( configuration.SearchUrl, Uri.EscapeDataString(searchName), postAge); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; HttpWebRequest request = WebRequest.Create(verificationGetUrl) as HttpWebRequest; //Mono does not support CreateHttp //request.ServerCertificateValidationCallback = ServerCertificateValidationCallback; //Not implemented in mono request.Method = "GET"; request.Timeout = 60 * 1000; HttpWebResponse response = request.GetResponse() as HttpWebResponse; if (response.StatusCode != HttpStatusCode.OK) { throw new Exception("Error when verifying on indexer: " + response.StatusCode + " " + response.StatusDescription); } using (var reader = new StreamReader(response.GetResponseStream())) { var responseBody = reader.ReadToEnd(); if (responseBody.IndexOf("<error code=") >= 0) { throw new Exception("Error when verifying on indexer: " + responseBody); } using (XmlReader xmlReader = XmlReader.Create(new StringReader(responseBody))) { SyndicationFeed feed = SyndicationFeed.Load(xmlReader); foreach (var item in feed.Items) { Decimal similarityPercentage = LevenshteinDistance.SimilarityPercentage(CleanGeekBug(item.Title.Text), upload.CleanedName); if (similarityPercentage > configuration.VerifySimilarityPercentageTreshold) { return(true); } Decimal similarityPercentageWithIndexCleanedName = LevenshteinDistance.SimilarityPercentage(CleanGeekBug(item.Title.Text), searchName); if (similarityPercentageWithIndexCleanedName > configuration.VerifySimilarityPercentageTreshold) { return(true); } } } } return(false); }
private void UploadNextItemInQueue() { try { UploadEntry nextUpload = DBHandler.Instance.GetNextUploadEntryToUpload(); if (nextUpload == null) { return; } WatchFolderSettings folderConfiguration = configuration.GetWatchFolderSettings(nextUpload.WatchFolderShortName); FileSystemInfo toUpload; Boolean isDirectory; String fullPath = Path.Combine( configuration.BackupFolder.FullName, folderConfiguration.ShortName, nextUpload.Name); try { FileAttributes attributes = File.GetAttributes(fullPath); if (attributes.HasFlag(FileAttributes.Directory)) { isDirectory = true; toUpload = new DirectoryInfo(fullPath); } else { isDirectory = false; toUpload = new FileInfo(fullPath); } } catch (FileNotFoundException) { log.WarnFormat("Can no longer find {0} in the backup folder, cancelling upload", nextUpload.Name); nextUpload.Cancelled = true; DBHandler.Instance.UpdateUploadEntry(nextUpload); return; } if (nextUpload.UploadAttempts >= configuration.MaxRepostCount) { log.WarnFormat("Cancelling the upload after {0} retry attempts.", nextUpload.UploadAttempts); nextUpload.Cancelled = true; DirectoryInfo failedPostFolder = new DirectoryInfo( Path.Combine(configuration.PostFailedFolderString, folderConfiguration.ShortName)); toUpload.Move(failedPostFolder); DBHandler.Instance.UpdateUploadEntry(nextUpload); return; } PostRelease(folderConfiguration, nextUpload, toUpload, isDirectory); } catch (Exception ex) { log.Error("The upload failed to post. Retrying.", ex); } }
private void AddItemToPostingDb(FileSystemInfo toPost) { UploadEntry newUploadentry = new UploadEntry(); newUploadentry.CreatedAt = DateTime.UtcNow; newUploadentry.Name = toPost.Name; newUploadentry.RemoveAfterVerify = configuration.RemoveAfterVerify; newUploadentry.Cancelled = false; newUploadentry.Size = toPost.Size(); if (newUploadentry.Size == 0) log.ErrorFormat("File added with a size of 0 bytes, This cannot be uploaded! File name: [{0}]", toPost.FullName); DBHandler.Instance.AddNewUploadEntry(newUploadentry); }
public void UpdateUploadEntry(UploadEntry uploadEntry) { lock (lockObject) using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteCommand cmd = conn.CreateCommand()) { cmd.CommandText = @"UPDATE UploadEntries SET Name = @name, CleanedName = @cleanedName, ObscuredName = @ObscuredName, RemoveAfterVerify = @removeAfterVerify, UploadedAt = @uploadedAt, NotifiedIndexerAt = @notifiedIndexerAt, SeenOnIndexerAt = @seenOnIndexerAt, Cancelled = @cancelled, WatchFolderShortName = @watchFolderShortName, UploadAttempts = @uploadAttempts, RarPassword = @rarPassword, PriorityNum = @priorityNum, NzbContents = @nzbContents, IsRepost = @isRepost, NotificationCount = @notificationCount, CurrentLocation = @currentLocation, HasNfo = @hasNfo WHERE RowIDAlias = @rowIDAlias"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadEntry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadEntry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadEntry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadEntry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadEntry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadEntry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadEntry.Cancelled))); cmd.Parameters.Add(new SqliteParameter("@watchFolderShortName", uploadEntry.WatchFolderShortName)); cmd.Parameters.Add(new SqliteParameter("@uploadAttempts", uploadEntry.UploadAttempts)); cmd.Parameters.Add(new SqliteParameter("@rarPassword", uploadEntry.RarPassword)); cmd.Parameters.Add(new SqliteParameter("@priorityNum", uploadEntry.PriorityNum)); cmd.Parameters.Add(new SqliteParameter("@nzbContents", uploadEntry.NzbContents)); cmd.Parameters.Add(new SqliteParameter("@isRepost", GetDbValue(uploadEntry.IsRepost))); cmd.Parameters.Add(new SqliteParameter("@notificationCount", uploadEntry.NotificationCount)); cmd.Parameters.Add(new SqliteParameter("@currentLocation", GetDbValue(uploadEntry.CurrentLocation))); cmd.Parameters.Add(new SqliteParameter("@hasNfo", GetDbValue(uploadEntry.HasNfo))); cmd.Parameters.Add(new SqliteParameter("@rowIDAlias", uploadEntry.ID)); cmd.ExecuteNonQuery(); } } }
protected override void VerifyEntryOnIndexer(UploadEntry upload) { if (UploadIsOnIndexer(upload)) { upload.SeenOnIndexAt = DateTime.UtcNow; DBHandler.Instance.UpdateUploadEntry(upload); log.InfoFormat("Release [{0}] has been found on the indexer.", upload.CleanedName); if (upload.RemoveAfterVerify) { upload.Delete(Configuration); } } }
private void RepostIfRequired(UploadEntry upload) { var ageInMinutes = (DateTime.UtcNow - upload.UploadedAt.Value).TotalMinutes; if (!(ageInMinutes > configuration.RepostAfterMinutes)) { return; } log.WarnFormat("Could not find [{0}] after {1} minutes, reposting, attempt {2}", upload.Name, configuration.RepostAfterMinutes, upload.UploadAttempts); upload.UploadedAt = null; DBHandler.Instance.UpdateUploadEntry(upload); }
protected override Boolean UploadIsOnIndexer(UploadEntry upload) { String verificationGetUrl = String.Format(Configuration.SearchUrl, upload.ObscuredName); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; HttpWebRequest request = WebRequest.Create(verificationGetUrl) as HttpWebRequest; //Mono does not support CreateHttp //request.ServerCertificateValidationCallback = ServerCertificateValidationCallback; //Not implemented in mono request.Method = "GET"; request.Timeout = 60 * 1000; HttpWebResponse response; try { response = request.GetResponse() as HttpWebResponse; } catch (WebException ex) { response = ex.Response as HttpWebResponse; } using (var reader = new StreamReader(response.GetResponseStream())) { var responseBody = reader.ReadToEnd(); switch (response.StatusCode) { case HttpStatusCode.OK: log.InfoFormat("The release {0} was found on indexer. Response: {1}", upload.CleanedName, responseBody); return(true); case HttpStatusCode.NotFound: log.InfoFormat("The release {0} was NOT found on indexer. Response: {1}", upload.CleanedName, responseBody); RepostIfRequired(upload); return(false); case HttpStatusCode.InternalServerError: HandleServerError(upload, responseBody); return(false); default: throw new Exception("Error when verifying on indexer: " + response.StatusCode + " " + response.StatusDescription + " " + responseBody); } } }
protected virtual void RepostIfRequired(UploadEntry upload) { var ageInMinutes = (DateTime.UtcNow - upload.UploadedAt.Value).TotalMinutes; if (ageInMinutes > Configuration.RepostAfterMinutes) { log.WarnFormat("Could not find [{0}] after {1} minutes, reposting, attempt {2}", upload.CleanedName, Configuration.RepostAfterMinutes, upload.UploadAttempts); upload.UploadedAt = null; upload.Move(Configuration, Location.Queue); DBHandler.Instance.UpdateUploadEntry(upload); } else { log.InfoFormat("A repost of [{0}] is not required as {1} minutes have not passed since upload.", upload.CleanedName, Configuration.RepostAfterMinutes); } }
private void RepostIfRequired(UploadEntry upload) { var AgeInMinutes = (DateTime.UtcNow - upload.UploadedAt.Value).TotalMinutes; if(AgeInMinutes > configuration.RepostAfterMinutes) { log.WarnFormat("Could not find [{0}] after {1} minutes, reposting.", upload.Name, configuration.RepostAfterMinutes); UploadEntry repost = new UploadEntry(); repost.Name = upload.Name; repost.RemoveAfterVerify = upload.RemoveAfterVerify; repost.Cancelled = false; repost.Size = upload.Size; DBHandler.Instance.AddNewUploadEntry(repost); //This implicitly cancels all other uploads with the same name so no need to update the upload itself. } }
private void AddItemToPostingDb(FileSystemInfo toPost, WatchFolderSettings folderConfiguration) { UploadEntry newUploadentry = new UploadEntry(); newUploadentry.WatchFolderShortName = folderConfiguration.ShortName; newUploadentry.CreatedAt = DateTime.UtcNow; newUploadentry.Name = toPost.Name; newUploadentry.RemoveAfterVerify = configuration.RemoveAfterVerify; newUploadentry.Cancelled = false; newUploadentry.Size = toPost.Size(); newUploadentry.PriorityNum = folderConfiguration.Priority; if (newUploadentry.Size == 0) { log.ErrorFormat("File added with a size of 0 bytes, This cannot be uploaded! File name: [{0}]", toPost.FullName); return; } DBHandler.Instance.AddNewUploadEntry(newUploadentry); }
protected override void NotifyIndexerOfObfuscatedUpload(UploadEntry upload) { if (upload.UploadedAt != null) { String notificationUrl = String.Format(Configuration.ObfuscatedNotificationUrl); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; Byte[] nzbFileArray = UTF8Encoding.Default.GetBytes(upload.NzbContents); HttpClient httpClient = new HttpClient(); MultipartFormDataContent form = new MultipartFormDataContent(); form.Add(new ByteArrayContent(nzbFileArray), Configuration.NzbPostFilenameParam, upload.CleanedName + ".nzb"); if (!String.IsNullOrWhiteSpace(Configuration.NzbPostExtraParams)) { var extraParams = Configuration.NzbPostExtraParams.Split(new Char[] { '&' }, StringSplitOptions.RemoveEmptyEntries); foreach (var extraParam in extraParams) { var keyAndValue = extraParam.Split(new Char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (keyAndValue.Length != 2) { throw new Exception("Configuration error, NzbPostExtraParams is specified, but not in key=value&key2=value2 format."); } form.Add(new StringContent(keyAndValue[1]), keyAndValue[0]); } } HttpResponseMessage response = httpClient.PostAsync(notificationUrl, form).Result; HttpContent content = response.Content; String contentString = content.ReadAsStringAsync().Result; if (response.StatusCode != HttpStatusCode.OK) { throw new Exception("Error when notifying indexer: " + response.StatusCode + " " + response.ReasonPhrase + " " + contentString); } } }
protected virtual void VerifyEntryOnIndexer(UploadEntry upload) { if (UploadIsOnIndexer(upload)) { upload.SeenOnIndexAt = DateTime.UtcNow; DBHandler.Instance.UpdateUploadEntry(upload); log.InfoFormat("Release [{0}] has been found on the indexer.", upload.CleanedName); if (upload.RemoveAfterVerify) { upload.Delete(Configuration); } } else { log.WarnFormat( "Release [{0}] has NOT been found on the indexer. Checking if a repost is required.", upload.CleanedName); RepostIfRequired(upload); } }
private void AddItemToPostingDb(FileSystemInfo toPost, WatchFolderSettings folderConfiguration) { #pragma warning disable IDE0017 // Simplify object initialization UploadEntry newUploadentry = new UploadEntry(); #pragma warning restore IDE0017 // Simplify object initialization newUploadentry.WatchFolderShortName = folderConfiguration.ShortName; newUploadentry.CreatedAt = DateTime.UtcNow; newUploadentry.Name = toPost.Name; newUploadentry.RemoveAfterVerify = configuration.RemoveAfterVerify; newUploadentry.Cancelled = false; newUploadentry.Size = toPost.Size(); newUploadentry.PriorityNum = folderConfiguration.Priority; newUploadentry.CurrentLocation = Location.Queue; if (newUploadentry.Size == 0) { log.ErrorFormat("File added with a size of 0 bytes, This cannot be uploaded! File name: [{0}]", toPost.FullName); return; } DBHandler.Instance.AddNewUploadEntry(newUploadentry); }
public void UpdateUploadEntry(UploadEntry uploadEntry) { using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteCommand cmd = conn.CreateCommand()) { cmd.CommandText = @"UPDATE UploadEntries SET Name = @name, CleanedName = @cleanedName, ObscuredName = @ObscuredName, RemoveAfterVerify = @removeAfterVerify, UploadedAt = @uploadedAt, NotifiedIndexerAt = @notifiedIndexerAt, SeenOnIndexerAt = @seenOnIndexerAt, Cancelled = @cancelled, WatchFolderShortName = @watchFolderShortName, UploadAttempts = @uploadAttempts, RarPassword = @rarPassword, PriorityNum = @priorityNum WHERE ROWID = @rowId"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadEntry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadEntry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadEntry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadEntry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadEntry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadEntry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadEntry.Cancelled))); cmd.Parameters.Add(new SqliteParameter("@watchFolderShortName", uploadEntry.WatchFolderShortName)); cmd.Parameters.Add(new SqliteParameter("@uploadAttempts", uploadEntry.UploadAttempts)); cmd.Parameters.Add(new SqliteParameter("@rarPassword", uploadEntry.RarPassword)); cmd.Parameters.Add(new SqliteParameter("@priorityNum", uploadEntry.PriorityNum)); cmd.Parameters.Add(new SqliteParameter("@rowId", uploadEntry.ID)); cmd.ExecuteNonQuery(); } } }
private DirectoryInfo PrepareDirectoryForPosting(WatchFolderSettings folderConfiguration, UploadEntry nextUpload, DirectoryInfo toUpload) { String destination; if (folderConfiguration.UseObfuscation) { destination = Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName, nextUpload.ObscuredName); } else { destination = Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName, nextUpload.CleanedName); } if (!Directory.Exists(Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName))) { Directory.CreateDirectory(Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName)); } ((DirectoryInfo)toUpload).Copy(destination, true); return(new DirectoryInfo(destination)); }
private FileInfo PrepareFileForPosting(WatchFolderSettings folderConfiguration, UploadEntry nextUpload, FileInfo toUpload) { String destination; if (folderConfiguration.UseObfuscation) { destination = Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName, nextUpload.ObscuredName + toUpload.Extension); } else { destination = Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName, nextUpload.CleanedName + toUpload.Extension); } if (!Directory.Exists(Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName))) { Directory.CreateDirectory(Path.Combine(configuration.WorkingFolder.FullName, folderConfiguration.ShortName)); } ((FileInfo)toUpload).CopyTo(destination, true); FileInfo preparedFile = new FileInfo(destination); if (folderConfiguration.StripFileMetadata) { StripMetaDataFromFile(preparedFile); } return(preparedFile); }
private void RepostIfRequired(UploadEntry upload) { var ageInMinutes = (DateTime.UtcNow - upload.UploadedAt.Value).TotalMinutes; if (!(ageInMinutes > configuration.RepostAfterMinutes)) return; log.WarnFormat("Could not find [{0}] after {1} minutes, reposting, attempt {2}", upload.Name, configuration.RepostAfterMinutes, upload.UploadAttempts); upload.UploadedAt = null; DBHandler.Instance.UpdateUploadEntry(upload); }
private void PostRelease(WatchFolderSettings folderConfiguration, UploadEntry nextUpload, FileSystemInfo toUpload, Boolean isDirectory) { nextUpload.UploadAttempts++; if (folderConfiguration.CleanName) { nextUpload.CleanedName = folderConfiguration.PreTag + CleanName(toUpload.NameWithoutExtension()) + folderConfiguration.PostTag; } else { nextUpload.CleanedName = folderConfiguration.PreTag + toUpload.NameWithoutExtension() + folderConfiguration.PostTag; } if (folderConfiguration.UseObfuscation) { nextUpload.ObscuredName = Guid.NewGuid().ToString("N"); nextUpload.NotifiedIndexerAt = null; } DBHandler.Instance.UpdateUploadEntry(nextUpload); //This ensures we already notify the indexer of our obfuscated post before we start posting. UsenetPoster poster = new UsenetPoster(configuration, folderConfiguration); FileSystemInfo toPost = null; try { if (isDirectory) { toPost = PrepareDirectoryForPosting(folderConfiguration, nextUpload, (DirectoryInfo)toUpload); } else { toPost = PrepareFileForPosting(folderConfiguration, nextUpload, (FileInfo)toUpload); } String password = folderConfiguration.RarPassword; if (folderConfiguration.ApplyRandomPassword) { password = Guid.NewGuid().ToString("N"); } var nzbFile = poster.PostToUsenet(toPost, password, false); if (configuration.NzbOutputFolder != null) { nzbFile.Save(Path.Combine(configuration.NzbOutputFolder.FullName, nextUpload.CleanedName + ".nzb")); } nextUpload.RarPassword = password; nextUpload.UploadedAt = DateTime.UtcNow; DBHandler.Instance.UpdateUploadEntry(nextUpload); log.InfoFormat("[{0}] was uploaded as obfuscated release [{1}] to usenet." , nextUpload.CleanedName, nextUpload.ObscuredName); } finally { if (toPost != null) { toPost.Refresh(); if (toPost.Exists) { FileAttributes attributes = File.GetAttributes(toPost.FullName); if (attributes.HasFlag(FileAttributes.Directory)) { Directory.Delete(toPost.FullName, true); } else { File.Delete(toPost.FullName); } } } } }
private void PostRelease(UploadEntry nextUpload, FileSystemInfo toUpload, Boolean isDirectory) { nextUpload.CleanedName = CleanName(toUpload.NameWithoutExtension()) + configuration.PostTag; if (configuration.UseObfuscation) { nextUpload.ObscuredName = Guid.NewGuid().ToString("N"); nextUpload.NotifiedIndexerAt = null; DBHandler.Instance.UpdateUploadEntry(nextUpload); //This ensures we already notify the indexer of our obfuscated post before we start posting. } FileSystemInfo toPost = null; try { if (isDirectory) { toPost = PrepareDirectoryForPosting(nextUpload, (DirectoryInfo)toUpload); } else { toPost = PrepareFileForPosting(nextUpload, (FileInfo)toUpload); } var nzbFile = poster.PostToUsenet(toPost, false); if (!String.IsNullOrWhiteSpace(posterConfiguration.NzbOutputFolder)) nzbFile.Save(Path.Combine(posterConfiguration.NzbOutputFolder, nextUpload.CleanedName + ".nzb")); nextUpload.UploadedAt = DateTime.UtcNow; DBHandler.Instance.UpdateUploadEntry(nextUpload); } finally { if(toPost != null) { toPost.Refresh(); if(toPost.Exists) { FileAttributes attributes = File.GetAttributes(toPost.FullName); if (attributes.HasFlag(FileAttributes.Directory)) { Directory.Delete(toPost.FullName, true); } else { File.Delete(toPost.FullName); } } } } }
private Boolean UploadIsOnIndexer(UploadEntry upload) { var postAge = (Int32)Math.Ceiling((DateTime.UtcNow - upload.UploadedAt.Value).TotalDays + 1); String verificationGetUrl = String.Format( configuration.SearchUrl, Uri.EscapeDataString(upload.CleanedName), postAge); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; HttpWebRequest request = WebRequest.Create(verificationGetUrl) as HttpWebRequest; //Mono does not support CreateHttp //request.ServerCertificateValidationCallback = ServerCertificateValidationCallback; //Not implemented in mono request.Method = "GET"; request.Timeout = 60*1000; HttpWebResponse response = request.GetResponse() as HttpWebResponse; if(response.StatusCode != HttpStatusCode.OK) throw new Exception("Error when verifying on indexer: " + response.StatusCode + " " + response.StatusDescription); using(var reader = new StreamReader(response.GetResponseStream())) { var responseBody = reader.ReadToEnd(); if(responseBody.IndexOf("error") >= 0) throw new Exception("Error when verifying on indexer: " + responseBody); using (XmlReader xmlReader = XmlReader.Create(new StringReader(responseBody))) { SyndicationFeed feed = SyndicationFeed.Load(xmlReader); foreach (var item in feed.Items) { Decimal similarityPercentage = LevenshteinDistance.SimilarityPercentage(item.Title.Text, upload.CleanedName); if (similarityPercentage > configuration.VerifySimilarityPercentageTreshold) return true; } } } return false; }
private static UploadEntry GetUploadEntryFromReader(SqliteDataReader reader) { UploadEntry uploadEntry = new UploadEntry(); uploadEntry.ID = (Int64)reader["ROWID"]; uploadEntry.Name = reader["Name"] as String; uploadEntry.Size = (Int64)reader["Size"]; uploadEntry.CleanedName = reader["CleanedName"] as String; uploadEntry.ObscuredName = reader["ObscuredName"] as String; uploadEntry.RemoveAfterVerify = GetBoolean(reader["RemoveAfterVerify"]); uploadEntry.CreatedAt = GetDateTime(reader["CreatedAt"]); uploadEntry.UploadedAt = GetNullableDateTime(reader["UploadedAt"]); uploadEntry.NotifiedIndexerAt = GetNullableDateTime(reader["NotifiedIndexerAt"]); uploadEntry.SeenOnIndexAt = GetNullableDateTime(reader["SeenOnIndexerAt"]); uploadEntry.Cancelled = GetBoolean(reader["Cancelled"]); uploadEntry.WatchFolderShortName = reader["WatchFolderShortName"] as String; uploadEntry.UploadAttempts = (Int64) reader["UploadAttempts"]; uploadEntry.RarPassword = reader["RarPassword"] as String; return uploadEntry; }
private void PostRelease(WatchFolderSettings folderConfiguration, UploadEntry nextUpload, FileSystemInfo toUpload, Boolean isDirectory) { nextUpload.UploadAttempts++; if (folderConfiguration.CleanName) { nextUpload.CleanedName = ApplyTags(CleanName(folderConfiguration, StripNonAscii(toUpload.NameWithoutExtension())), folderConfiguration); } else { nextUpload.CleanedName = ApplyTags(StripNonAscii(toUpload.NameWithoutExtension()), folderConfiguration); } if (folderConfiguration.UseObfuscation) { nextUpload.ObscuredName = Guid.NewGuid().ToString("N"); nextUpload.NotifiedIndexerAt = null; } DBHandler.Instance.UpdateUploadEntry(nextUpload); UsenetPoster poster = new UsenetPoster(configuration, folderConfiguration); FileSystemInfo toPost = null; try { if (isDirectory) { toPost = PrepareDirectoryForPosting(folderConfiguration, nextUpload, (DirectoryInfo)toUpload); } else { toPost = PrepareFileForPosting(folderConfiguration, nextUpload, (FileInfo)toUpload); } String password = folderConfiguration.RarPassword; if (folderConfiguration.ApplyRandomPassword) { password = Guid.NewGuid().ToString("N"); } var nzbFile = poster.PostToUsenet(toPost, password, false); nextUpload.NzbContents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine + nzbFile.ToString(); if (configuration.NzbOutputFolder != null) { FileInfo file = new FileInfo(Path.Combine(configuration.NzbOutputFolder.FullName, nextUpload.CleanedName + ".nzb")); File.WriteAllText(file.FullName, nextUpload.NzbContents); } nextUpload.RarPassword = password; nextUpload.UploadedAt = DateTime.UtcNow; nextUpload.Move(configuration, Location.Backup); DBHandler.Instance.UpdateUploadEntry(nextUpload); log.InfoFormat("[{0}] was uploaded as obfuscated release [{1}] to usenet." , nextUpload.CleanedName, nextUpload.ObscuredName); } finally { if (toPost != null) { toPost.Refresh(); if (toPost.Exists) { FileAttributes attributes = File.GetAttributes(toPost.FullName); if (attributes.HasFlag(FileAttributes.Directory)) { Directory.Delete(toPost.FullName, true); } else { File.Delete(toPost.FullName); } } } } }
private void NotifyIndexerOfObfuscatedUpload(UploadEntry upload) { String notificationGetUrl = String.Format( configuration.ObfuscatedNotificationUrl, Uri.EscapeDataString(upload.ObscuredName), Uri.EscapeDataString(upload.CleanedName)); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; HttpWebRequest request = WebRequest.Create(notificationGetUrl) as HttpWebRequest; //Mono does not support CreateHttp //request.ServerCertificateValidationCallback = ServerCertificateValidationCallback; //Not implemented in mono request.Method = "GET"; request.Timeout = 60 * 1000; HttpWebResponse response = request.GetResponse() as HttpWebResponse; if (response.StatusCode != HttpStatusCode.OK) throw new Exception("Error when notifying indexer: " + response.StatusCode + " " + response.StatusDescription); using(var reader = new StreamReader(response.GetResponseStream())) { var responseBody = reader.ReadToEnd(); if(responseBody.IndexOf("error") >= 0) throw new Exception("Error when notifying indexer: " + responseBody); } }
public void UpdateUploadEntry(UploadEntry uploadEntry) { using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteCommand cmd = conn.CreateCommand()) { cmd.CommandText = @"UPDATE UploadEntries SET Name = @name, CleanedName = @cleanedName, ObscuredName = @ObscuredName, RemoveAfterVerify = @removeAfterVerify, UploadedAt = @uploadedAt, NotifiedIndexerAt = @notifiedIndexerAt, SeenOnIndexerAt = @seenOnIndexerAt, Cancelled = @cancelled, WatchFolderShortName = @watchFolderShortName, UploadAttempts = @uploadAttempts, RarPassword = @rarPassword WHERE ROWID = @rowId"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadEntry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadEntry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadEntry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadEntry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadEntry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadEntry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadEntry.Cancelled))); cmd.Parameters.Add(new SqliteParameter("@watchFolderShortName", uploadEntry.WatchFolderShortName)); cmd.Parameters.Add(new SqliteParameter("@uploadAttempts", uploadEntry.UploadAttempts)); cmd.Parameters.Add(new SqliteParameter("@rarPassword", uploadEntry.RarPassword)); cmd.Parameters.Add(new SqliteParameter("@rowId", uploadEntry.ID)); cmd.ExecuteNonQuery(); } } }
protected abstract void NotifyIndexerOfObfuscatedUpload(UploadEntry upload);
protected override Boolean UploadIsOnIndexer(UploadEntry upload) { return(true); }
public void AddNewUploadEntry(UploadEntry uploadEntry) { lock (lockObject) using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteTransaction trans = conn.BeginTransaction()) { using (SqliteCommand cmd = conn.CreateCommand()) { cmd.Transaction = trans; cmd.CommandText = @"UPDATE UploadEntries SET Cancelled = 1 WHERE Name = @name AND Cancelled = 0"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); Int32 cancelledEntries = cmd.ExecuteNonQuery(); if (cancelledEntries > 0) { log.InfoFormat("{0} upload entries were cancelled by a re-add of an existing upload.", cancelledEntries); } cmd.CommandText = @"INSERT INTO UploadEntries( Name, Size, CleanedName, ObscuredName, RemoveAfterVerify, CreatedAt, UploadedAt, NotifiedIndexerAt, SeenOnIndexerAt, Cancelled, WatchFolderShortName, UploadAttempts, RarPassword, PriorityNum, NzbContents, IsRepost, NotificationCount, CurrentLocation) VALUES( @name, @size, @cleanedName, @ObscuredName, @removeAfterVerify, @createdAt, @uploadedAt, @notifiedIndexerAt, @seenOnIndexerAt, @cancelled, @watchFolderShortName, @uploadAttempts, @rarPassword, @priorityNum, @nzbContents, @isRepost, @notificationCount, @currentLocation)"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.Parameters.Add(new SqliteParameter("@size", uploadEntry.Size)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadEntry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadEntry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadEntry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@createdAt", GetDbValue(uploadEntry.CreatedAt))); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadEntry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadEntry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadEntry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadEntry.Cancelled))); cmd.Parameters.Add(new SqliteParameter("@watchFolderShortName", uploadEntry.WatchFolderShortName)); cmd.Parameters.Add(new SqliteParameter("@uploadAttempts", uploadEntry.UploadAttempts)); cmd.Parameters.Add(new SqliteParameter("@rarPassword", uploadEntry.RarPassword)); cmd.Parameters.Add(new SqliteParameter("@priorityNum", uploadEntry.PriorityNum)); cmd.Parameters.Add(new SqliteParameter("@nzbContents", uploadEntry.NzbContents)); cmd.Parameters.Add(new SqliteParameter("@isRepost", GetDbValue(uploadEntry.IsRepost))); cmd.Parameters.Add(new SqliteParameter("@notificationCount", uploadEntry.NotificationCount)); cmd.Parameters.Add(new SqliteParameter("@currentLocation", GetDbValue(uploadEntry.CurrentLocation))); cmd.ExecuteNonQuery(); cmd.CommandText = "select last_insert_rowid()"; cmd.Parameters.Clear(); uploadEntry.ID = (Int64)cmd.ExecuteScalar(); } trans.Commit(); } } }
private FileInfo PrepareFileForPosting(UploadEntry nextUpload, FileInfo toUpload) { String destination; if (configuration.UseObfuscation) destination = Path.Combine(posterConfiguration.WorkingFolder.FullName, nextUpload.ObscuredName + toUpload.Extension); else destination = Path.Combine(posterConfiguration.WorkingFolder.FullName, nextUpload.CleanedName + toUpload.Extension); ((FileInfo)toUpload).CopyTo(destination, true); FileInfo preparedFile = new FileInfo(destination); if(configuration.StripFileMetadata) { StripMetaDataFromFile(preparedFile); } return preparedFile; }
protected abstract Boolean UploadIsOnIndexer(UploadEntry upload);
public void AddNewUploadEntry(UploadEntry uploadEntry) { using (SqliteConnection conn = new SqliteConnection(_connectionString)) { conn.Open(); using (SqliteTransaction trans = conn.BeginTransaction()) { using (SqliteCommand cmd = conn.CreateCommand()) { cmd.Transaction = trans; cmd.CommandText = @"UPDATE UploadEntries SET Cancelled = 1 WHERE Name = @name"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.ExecuteNonQuery(); //TODO: log here how many other entries were cancelled. cmd.CommandText = @"INSERT INTO UploadEntries( Name, Size, CleanedName, ObscuredName, RemoveAfterVerify, CreatedAt, UploadedAt, NotifiedIndexerAt, SeenOnIndexerAt, Cancelled, WatchFolderShortName, UploadAttempts, RarPassword, PriorityNum) VALUES( @name, @size, @cleanedName, @ObscuredName, @removeAfterVerify, @createdAt, @uploadedAt, @notifiedIndexerAt, @seenOnIndexerAt, @cancelled, @watchFolderShortName, @uploadAttempts, @rarPassword, @priorityNum)"; cmd.Parameters.Add(new SqliteParameter("@name", uploadEntry.Name)); cmd.Parameters.Add(new SqliteParameter("@size", uploadEntry.Size)); cmd.Parameters.Add(new SqliteParameter("@cleanedName", uploadEntry.CleanedName)); cmd.Parameters.Add(new SqliteParameter("@ObscuredName", uploadEntry.ObscuredName)); cmd.Parameters.Add(new SqliteParameter("@removeAfterVerify", uploadEntry.RemoveAfterVerify)); cmd.Parameters.Add(new SqliteParameter("@createdAt", GetDbValue(uploadEntry.CreatedAt))); cmd.Parameters.Add(new SqliteParameter("@uploadedAt", GetDbValue(uploadEntry.UploadedAt))); cmd.Parameters.Add(new SqliteParameter("@notifiedIndexerAt", GetDbValue(uploadEntry.NotifiedIndexerAt))); cmd.Parameters.Add(new SqliteParameter("@seenOnIndexerAt", GetDbValue(uploadEntry.SeenOnIndexAt))); cmd.Parameters.Add(new SqliteParameter("@cancelled", GetDbValue(uploadEntry.Cancelled))); cmd.Parameters.Add(new SqliteParameter("@watchFolderShortName", uploadEntry.WatchFolderShortName)); cmd.Parameters.Add(new SqliteParameter("@uploadAttempts", uploadEntry.UploadAttempts)); cmd.Parameters.Add(new SqliteParameter("@rarPassword", uploadEntry.RarPassword)); cmd.Parameters.Add(new SqliteParameter("@priorityNum", uploadEntry.PriorityNum)); cmd.ExecuteNonQuery(); cmd.CommandText = "select last_insert_rowid()"; cmd.Parameters.Clear(); uploadEntry.ID = (Int64)cmd.ExecuteScalar(); } trans.Commit(); } } }
private DirectoryInfo PrepareDirectoryForPosting(UploadEntry nextUpload, DirectoryInfo toUpload) { String destination; if (configuration.UseObfuscation) destination = Path.Combine(posterConfiguration.WorkingFolder.FullName, nextUpload.ObscuredName); else destination = Path.Combine(posterConfiguration.WorkingFolder.FullName, nextUpload.CleanedName); ((DirectoryInfo)toUpload).Copy(destination, true); return new DirectoryInfo(destination); }