diff --git a/Clients/ClientLocalDB.cs b/Clients/ClientLocalDB.cs deleted file mode 100644 index fda09ee..0000000 --- a/Clients/ClientLocalDB.cs +++ /dev/null @@ -1,1138 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.ClientLocalDB -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.SQLite; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; - -namespace TLO.local -{ - internal class ClientLocalDB - { - private static ClientLocalDB _current; - private SQLiteConnection _conn; - private static Logger _logger; - - public static ClientLocalDB Current - { - get - { - if (ClientLocalDB._current == null) - ClientLocalDB._current = new ClientLocalDB(); - return ClientLocalDB._current; - } - } - - public string FileDatabase - { - get - { - return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Database.db"); - } - } - - private ClientLocalDB() - { - if (ClientLocalDB._logger == null) - ClientLocalDB._logger = LogManager.GetLogger("ClientServer"); - bool flag = false; - if (!File.Exists(this.FileDatabase)) - flag = true; - try - { - _conn = new DBConnectionCreator().Connection; - } - catch - { - flag = true; - } - if (flag) - this.CreateDatabase(); - this.SaveToDatabase(); - this.UpdateDataBase(); - } - - public void SaveToDatabase() - { - if (!DBConnectionCreator.InMemory()) - { - // не нужно пересохранять в БД если, она не хранится в памяти. - return; - } - try - { - if (File.Exists(this.FileDatabase + ".tmp")) - File.Delete(this.FileDatabase + ".tmp"); - using (SQLiteConnection destination = new SQLiteConnection(string.Format("Data Source={0};Version=3;", (object) (this.FileDatabase + ".tmp")))) - { - destination.Open(); - this._conn.BackupDatabase(destination, "main", "main", -1, null, -1); - destination.Close(); - } - } - catch (Exception ex) - { - ClientLocalDB._logger.Error(ex.Message + "\r\n" + ex.StackTrace); - } - if (!File.Exists(this.FileDatabase + ".tmp")) - return; - _conn?.Close(); - if (File.Exists(this.FileDatabase)) - File.Delete(this.FileDatabase); - File.Move(this.FileDatabase + ".tmp", this.FileDatabase); - this._conn = new DBConnectionCreator().Connection; - } - - private void CreateDatabase() - { - _conn?.Close(); - if (File.Exists(this.FileDatabase)) - File.Delete(this.FileDatabase); - _conn = new DBConnectionCreator().Connection; - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "\r\nCREATE TABLE Category(CategoryID INTEGER PRIMARY KEY ASC, ParentID INTEGER, OrderID INT, Name TEXT NOT NULL, FullName TEXT NOT NULL, IsEnable BIT, CountSeeders int, \r\n TorrentClientUID TEXT, Folder TEXT, AutoDownloads INT, LastUpdateTopics DATETIME, LastUpdateStatus DATETIME, Label TEXT, ReportTopicID INT);\r\nCREATE TABLE Topic (TopicID INT PRIMARY KEY ASC, CategoryID INT, Name TEXT, Hash TEXT, Size INTEGER, Seeders INT, AvgSeeders DECIMAL(18,4), Status INT, IsActive BIT, IsDeleted BIT, IsKeep BIT, IsKeepers BIT, IsBlackList BIT, IsDownload BIT, RegTime DATETIME, PosterID INT);\r\nCREATE INDEX IX_Topic__Hash ON Topic (Hash);\r\nCREATE TABLE TopicStatusHystory (TopicID INT NOT NULL, Date DateTime NOT NULL, Seeders INT, PRIMARY KEY(TopicID ASC, Date ASC));\r\nCREATE TABLE TorrentClient(UID NVARCHAR(50) PRIMARY KEY ASC NOT NULL, Name NVARCHAR(100) NOT NULL, Type VARCHAR(50) NOT NULL, ServerName NVARCHAR(50) NOT NULL, ServerPort INT NOT NULL, UserName NVARCHAR(50), UserPassword NVARCHAR(50), LastReadHash DATETIME);\r\nCREATE TABLE Report(CategoryID INT NOT NULL, ReportNo INT NOT NULL, URL TEXT, Report TEXT, PRIMARY KEY(CategoryID ASC, ReportNo ASC));\r\nCREATE TABLE Keeper (KeeperName nvarchar(100) not null, CategoryID int not null, Count INT NOT NULL, Size DECIMAL(18,4) NOT NULL, PRIMARY KEY(KeeperName ASC, CategoryID ASC));\r\nCREATE TABLE KeeperToTopic(KeeperName NVARCHAR(50) NOT NULL, CategoryID INT NULL, TopicID INT NOT NULL, PRIMARY KEY(KeeperName ASC, TopicID ASC));\r\nCREATE TABLE User (UserID INT PRIMARY KEY ASC NOT NULL, Name NVARCHAR(100) NOT NULL);\r\n"; - command.ExecuteNonQuery(); - } - } - - public void ClearDatabase() - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - HashSet intSet = new HashSet(); - command.Transaction = sqLiteTransaction; - command.CommandText = "DELETE FROM Topic"; - command.ExecuteNonQuery(); - command.CommandText = "DELETE FROM TopicStatusHystory"; - command.ExecuteNonQuery(); - command.CommandText = "UPDATE Report SET Report = ''"; - command.ExecuteNonQuery(); - } - sqLiteTransaction.Commit(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "vacuum;"; - command.ExecuteNonQuery(); - } - } - } - - public void UpdateDataBase() - { - using (var command = _conn.CreateCommand()) - { - var updated = false; - command.CommandText = "PRAGMA user_version"; - var result = (long)command.ExecuteScalar(); - for (var i = 0; i <= 1; i++, result++) - { - switch (result) - { - case 0: - command.CommandText = @"CREATE INDEX keepername_topicid_idx ON KeeperToTopic (TopicID, KeeperName)"; - command.ExecuteNonQuery(); - updated = true; - continue; - default: - command.CommandText = $"PRAGMA user_version={i}"; - command.ExecuteNonQuery(); - break; - } - } - - if (updated) - { - this.SaveToDatabase(); - } - } - } - - public IEnumerable GetUsers() - { - List userInfoList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "SELECT * FROM User"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - userInfoList.Add(new UserInfo() - { - UserID = sqLiteDataReader.GetInt32(0), - Name = sqLiteDataReader.GetString(1) - }); - } - } - return (IEnumerable) userInfoList; - } - - public void SaveUsers(IEnumerable data) - { - if (data == null || data.Count() == 0) - return; - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "INSERT OR REPLACE INTO User(UserID, Name) VALUES(@UserID, @Name);"; - command.Parameters.Add("@UserID", DbType.Int32); - command.Parameters.Add("@Name", DbType.String); - command.Prepare(); - foreach (UserInfo userInfo in data) - { - command.Parameters[0].Value = (object) userInfo.UserID; - command.Parameters[1].Value = (object) (userInfo.Name ?? "<Удален>"); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public int[] GetNoUsers() - { - List intList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "\r\nSELECT DISTINCT t.PosterID\r\nFROM \r\n Topic AS t \r\n LEFT JOIN User AS u ON (t.PosterID = u.UserID) \r\nWHERE\r\n t.PosterID IS NOT NULL AND u.Name IS NULL"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - { - var posterId = sqLiteDataReader.GetInt32(0); - if (posterId > 0) - { - intList.Add(posterId); - } - } - } - } - return intList.ToArray(); - } - - public void CategoriesSave(IEnumerable data, bool isLoad = false) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - HashSet hash = new HashSet(); - command.Transaction = sqLiteTransaction; - command.CommandText = string.Format("select CategoryID FROM Category WHERE CategoryID IN ({0})", (object) string.Join(",", data.Select((Func) (x => x.CategoryID)))); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - hash.Add(sqLiteDataReader.GetInt32(0)); - } - if (isLoad) - { - command.CommandText = "UPDATE Category SET ParentID = @ParentID, OrderID = @OrderID, Name = @Name, FullName = @FullName WHERE CategoryID = @ID"; - IEnumerable source = data; - foreach (Category category in source.Where((Func) (x => hash.Contains(x.CategoryID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@ID", (object) category.CategoryID); - command.Parameters.AddWithValue("@ParentID", (object) category.ParentID); - command.Parameters.AddWithValue("@OrderID", (object) category.OrderID); - command.Parameters.AddWithValue("@Name", (object) category.Name); - command.Parameters.AddWithValue("@FullName", string.IsNullOrWhiteSpace(category.FullName) ? (object) category.Name : (object) category.FullName); - command.ExecuteNonQuery(); - } - } - else - { - command.CommandText = "UPDATE Category SET IsEnable = 0 WHERE IsEnable = 1"; - command.ExecuteNonQuery(); - command.CommandText = "UPDATE Category SET IsEnable = @IsEnable, Folder = @Folder, LastUpdateTopics = @LastUpdateTopics, LastUpdateStatus = @LastUpdateStatus, CountSeeders = @CountSeeders, TorrentClientUID = @TorrentClientUID, Label = @Label WHERE CategoryID = @ID"; - IEnumerable source = data; - foreach (Category category in source.Where((Func) (x => hash.Contains(x.CategoryID)))) - { - string str = string.Format("{0}|{1}|{2}|{3}", (object) category.Folder, (object) category.CreateSubFolder, category.IsSaveTorrentFiles ? (object) "1" : (object) "0", category.IsSaveWebPage ? (object) "1" : (object) "0"); - command.Parameters.Clear(); - command.Parameters.AddWithValue("@ID", (object) category.CategoryID); - command.Parameters.AddWithValue("@IsEnable", (object) category.IsEnable); - command.Parameters.AddWithValue("@CountSeeders", (object) category.CountSeeders); - command.Parameters.AddWithValue("@TorrentClientUID", (object) category.TorrentClientUID.ToString()); - command.Parameters.AddWithValue("@Folder", (object) str); - command.Parameters.AddWithValue("@LastUpdateTopics", (object) category.LastUpdateTopics); - command.Parameters.AddWithValue("@LastUpdateStatus", (object) category.LastUpdateStatus); - command.Parameters.AddWithValue("@Label", (object) category.Label); - command.ExecuteNonQuery(); - } - } - command.CommandText = "INSERT OR REPLACE INTO Category (CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, Label) \r\nVALUES(@ID, @ParentID, @OrderID, @Name, @FullName, @IsEnable, @Folder, @LastUpdateTopics, @LastUpdateStatus, @Label)"; - IEnumerable source1 = data; - foreach (Category category in source1.Where((Func) (x => !hash.Contains(x.CategoryID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@ID", (object) category.CategoryID); - command.Parameters.AddWithValue("@ParentID", (object) category.ParentID); - command.Parameters.AddWithValue("@OrderID", (object) category.OrderID); - command.Parameters.AddWithValue("@Name", (object) category.Name); - command.Parameters.AddWithValue("@FullName", string.IsNullOrWhiteSpace(category.FullName) ? (object) category.Name : (object) category.FullName); - command.Parameters.AddWithValue("@IsEnable", (object) category.IsEnable); - command.Parameters.AddWithValue("@CountSeeders", (object) category.CountSeeders); - command.Parameters.AddWithValue("@Folder", (object) category.Folder); - command.Parameters.AddWithValue("@LastUpdateTopics", (object) category.LastUpdateTopics); - command.Parameters.AddWithValue("@LastUpdateStatus", (object) category.LastUpdateStatus); - command.Parameters.AddWithValue("@Label", (object) category.Label); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public List GetCategories() - { - List categoryList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "\r\nSELECT CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, CountSeeders, TorrentClientUID, ReportTopicID, Label FROM Category"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - { - Category category = new Category() - { - CategoryID = sqLiteDataReader.GetInt32(0), - ParentID = sqLiteDataReader.GetInt32(1), - OrderID = sqLiteDataReader.GetInt32(2), - Name = sqLiteDataReader.GetString(3), - FullName = sqLiteDataReader.GetString(4), - IsEnable = sqLiteDataReader.GetBoolean(5), - CountSeeders = sqLiteDataReader.IsDBNull(9) ? 2 : sqLiteDataReader.GetInt32(9), - TorrentClientUID = sqLiteDataReader.IsDBNull(10) ? Guid.Empty : Guid.Parse(sqLiteDataReader.GetString(10)), - LastUpdateTopics = sqLiteDataReader.GetDateTime(7), - LastUpdateStatus = sqLiteDataReader.GetDateTime(8), - ReportList = sqLiteDataReader.IsDBNull(11) ? string.Empty : sqLiteDataReader.GetString(11), - Label = sqLiteDataReader.IsDBNull(12) ? string.Empty : sqLiteDataReader.GetString(12) - }; - string str = sqLiteDataReader.IsDBNull(6) ? (string) null : sqLiteDataReader.GetString(6); - if (!string.IsNullOrWhiteSpace(str)) - { - string[] strArray = str.Split('|'); - if (strArray.Length >= 1) - category.Folder = strArray[0]; - if (strArray.Length >= 2) - category.CreateSubFolder = int.Parse(strArray[1]); - if (strArray.Length >= 3) - { - category.IsSaveTorrentFiles = strArray[2] == "1"; - category.FolderTorrentFile = Path.Combine(category.Folder, "!!!Torrent-files!!!"); - } - if (strArray.Length >= 4) - { - category.IsSaveWebPage = strArray[3] == "1"; - category.FolderSavePageForum = Path.Combine(category.Folder, "!!!Web-pages!!!"); - } - } - categoryList.Add(category); - } - } - } - return categoryList; - } - - public List GetCategoriesEnable() - { - List categoryList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "\r\nSELECT CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, CountSeeders, TorrentClientUID, Label FROM Category WHERE IsEnable = 1 ORDER BY FullName"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - { - Category category = new Category() - { - CategoryID = sqLiteDataReader.GetInt32(0), - ParentID = sqLiteDataReader.GetInt32(1), - OrderID = sqLiteDataReader.GetInt32(2), - Name = sqLiteDataReader.GetString(3), - FullName = sqLiteDataReader.GetString(4), - IsEnable = sqLiteDataReader.GetBoolean(5), - CountSeeders = sqLiteDataReader.IsDBNull(9) ? 2 : sqLiteDataReader.GetInt32(9), - TorrentClientUID = sqLiteDataReader.IsDBNull(10) ? Guid.Empty : Guid.Parse(sqLiteDataReader.GetString(10)), - LastUpdateTopics = sqLiteDataReader.GetDateTime(7), - LastUpdateStatus = sqLiteDataReader.GetDateTime(8), - Label = sqLiteDataReader.IsDBNull(11) ? string.Empty : sqLiteDataReader.GetString(11) - }; - string str = sqLiteDataReader.IsDBNull(6) ? (string) null : sqLiteDataReader.GetString(6); - if (!string.IsNullOrWhiteSpace(str)) - { - string[] strArray = str.Split('|'); - if (strArray.Length >= 1) - category.Folder = strArray[0]; - if (strArray.Length >= 2) - category.CreateSubFolder = int.Parse(strArray[1]); - if (strArray.Length >= 3) - { - category.IsSaveTorrentFiles = strArray[2] == "1"; - category.FolderTorrentFile = Path.Combine(category.Folder, "!!!Torrent-files!!!"); - } - if (strArray.Length >= 4) - { - category.IsSaveWebPage = strArray[3] == "1"; - category.FolderSavePageForum = Path.Combine(category.Folder, "!!!Web-pages!!!"); - } - } - categoryList.Add(category); - } - } - } - return categoryList; - } - - public void ResetFlagsTopicDownloads() - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "UPDATE Topic SET IsKeep = 0, IsDownload = 0"; - command.ExecuteNonQuery(); - } - } - - public void SaveTopicInfo(List data, bool isUpdateTopic = false) - { - DateTime dateTime = new DateTime(2000, 1, 1); - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - if (isUpdateTopic) - { - command.CommandText = "UPDATE Category SET LastUpdateTopics = @LastUpdateTopics WHERE CategoryID = @CategoryID"; - foreach (int num in data.Select((Func) (x => x.CategoryID)).Distinct()) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@CategoryID", (object) num); - command.Parameters.AddWithValue("@LastUpdateTopics", (object) DateTime.Now); - command.ExecuteNonQuery(); - } - } - command.CommandText = string.Format("SELECT TopicID FROM Topic WHERE TopicID IN ({0})", (object) string.Join(",", data.Select((Func) (x => x.TopicID)))); - List list = new List(); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - list.Add(sqLiteDataReader.GetInt32(0)); - } - if (isUpdateTopic) - { - command.CommandText = "UPDATE Topic SET CategoryID = @CategoryID, Name = @Name, Hash = @Hash, Size = @Size, Seeders = @Seeders, Status = @Status, IsDeleted = @IsDeleted, RegTime = @RegTime, PosterID = @PosterID WHERE TopicID = @TopicID;"; - List source = data; - foreach (TopicInfo topicInfo in source.Where((Func) (x => list.Contains(x.TopicID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@TopicID", (object) topicInfo.TopicID); - command.Parameters.AddWithValue("@CategoryID", (object) topicInfo.CategoryID); - command.Parameters.AddWithValue("@Name", (object) topicInfo.Name2); - command.Parameters.AddWithValue("@Hash", (object) topicInfo.Hash); - command.Parameters.AddWithValue("@Size", (object) topicInfo.Size); - command.Parameters.AddWithValue("@Seeders", (object) topicInfo.Seeders); - command.Parameters.AddWithValue("@Status", (object) topicInfo.Status); - command.Parameters.AddWithValue("@IsDeleted", (object) 0); - command.Parameters.AddWithValue("@RegTime", (object) (topicInfo.RegTime < dateTime ? dateTime : topicInfo.RegTime)); - command.Parameters.AddWithValue("@PosterID", (object) topicInfo.PosterID); - command.ExecuteNonQuery(); - } - } - else - { - command.CommandText = "UPDATE Topic SET CategoryID = @CategoryID, Name = @Name, Hash = @Hash, Size = @Size, Seeders = @Seeders, Status = @Status, IsDeleted = @IsDeleted, IsKeep = @IsKeep, IsKeepers = @IsKeepers, IsBlackList = @IsBlackList, IsDownload = @IsDownload WHERE TopicID = @TopicID;"; - List source = data; - foreach (TopicInfo topicInfo in source.Where((Func) (x => list.Contains(x.TopicID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@TopicID", (object) topicInfo.TopicID); - command.Parameters.AddWithValue("@CategoryID", (object) topicInfo.CategoryID); - command.Parameters.AddWithValue("@Name", (object) topicInfo.Name2); - command.Parameters.AddWithValue("@Hash", (object) topicInfo.Hash); - command.Parameters.AddWithValue("@Size", (object) topicInfo.Size); - command.Parameters.AddWithValue("@Seeders", (object) topicInfo.Seeders); - command.Parameters.AddWithValue("@Status", (object) topicInfo.Status); - command.Parameters.AddWithValue("@IsDeleted", (object) 0); - command.Parameters.AddWithValue("@IsKeep", (object) topicInfo.IsKeep); - command.Parameters.AddWithValue("@IsKeepers", (object) topicInfo.IsKeeper); - command.Parameters.AddWithValue("@IsBlackList", (object) topicInfo.IsBlackList); - command.Parameters.AddWithValue("@IsDownload", (object) topicInfo.IsDownload); - command.ExecuteNonQuery(); - } - } - command.CommandText = "\r\nINSERT OR REPLACE INTO Topic (TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, RegTime, PosterID)\r\nVALUES(@TopicID, @CategoryID, @Name, @Hash, @Size, @Seeders, @Status, @IsActive, @IsDeleted, @IsKeep, @IsKeepers, @IsBlackList, @IsDownload, @RegTime, @PosterID);"; - List source1 = data; - foreach (TopicInfo topicInfo in source1.Where((Func) (x => !list.Contains(x.TopicID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@TopicID", (object) topicInfo.TopicID); - command.Parameters.AddWithValue("@CategoryID", (object) topicInfo.CategoryID); - command.Parameters.AddWithValue("@Name", (object) topicInfo.Name2); - command.Parameters.AddWithValue("@Hash", (object) topicInfo.Hash); - command.Parameters.AddWithValue("@Size", (object) topicInfo.Size); - command.Parameters.AddWithValue("@Seeders", (object) topicInfo.Seeders); - command.Parameters.AddWithValue("@Status", (object) topicInfo.Status); - command.Parameters.AddWithValue("@IsActive", (object) 1); - command.Parameters.AddWithValue("@IsDeleted", (object) 0); - command.Parameters.AddWithValue("@IsKeep", (object) topicInfo.IsKeep); - command.Parameters.AddWithValue("@IsKeepers", (object) topicInfo.IsKeeper); - command.Parameters.AddWithValue("@IsBlackList", (object) topicInfo.IsBlackList); - command.Parameters.AddWithValue("@IsDownload", (object) topicInfo.IsDownload); - command.Parameters.AddWithValue("@RegTime", (object) (topicInfo.RegTime < dateTime ? dateTime : topicInfo.RegTime)); - command.Parameters.AddWithValue("@PosterID", (object) topicInfo.PosterID); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - this.SaveStatus(data.Select((Func) (x => new int[2] - { - x.TopicID, - x.Seeders - })).ToArray(), true); - } - - internal void DeleteTopicsByCategoryId(int categoryID) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.Parameters.AddWithValue("@categoryID", (object) categoryID); - command.CommandText = "UPDATE Topic SET IsDeleted = 1 WHERE CategoryID = @categoryID;"; - command.ExecuteNonQuery(); - } - sqLiteTransaction.Commit(); - } - } - - public void ClearHistoryStatus() - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.Parameters.Add("@Date", DbType.DateTime); - command.Parameters[0].Value = (object) DateTime.Now.Date.AddDays((double) -Settings.Current.CountDaysKeepHistory); - command.CommandText = "DELETE FROM TopicStatusHystory WHERE Date <= @Date;"; - command.ExecuteNonQuery(); - } - sqLiteTransaction.Commit(); - } - } - - public void SaveStatus(int[][] data, bool isUpdateStatus = false) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "\r\nUPDATE Topic SET Seeders = @Seeders WHERE TopicID = @TopicID;\r\nINSERT OR REPLACE INTO TopicStatusHystory VALUES(@TopicID, @Date, @Seeders);\r\n"; - if (Settings.Current.IsNotSaveStatistics) - command.CommandText = "UPDATE Topic SET Seeders = @Seeders WHERE TopicID = @TopicID;"; - command.Parameters.Clear(); - command.Parameters.Add("@Date", DbType.DateTime); - command.Parameters.Add("@TopicID", DbType.Int32); - command.Parameters.Add("@Seeders", DbType.Int32); - command.Parameters[0].Value = (object) DateTime.Now; - foreach (int[] numArray in data) - { - command.Parameters[1].Value = (object) numArray[0]; - command.Parameters[2].Value = (object) numArray[1]; - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public List GetTopicsByCategory(int categoyid) - { - DateTime dateTime = new DateTime(2000, 1, 1); - List topicInfoList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "SELECT TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, PosterID\r\nFROM Topic WHERE (CategoryID = @CategoryID OR @CategoryID = -1) AND IsDeleted = 0 AND Status NOT IN (7,4,11,5) and Hash IS NOT NULL"; - command.Parameters.AddWithValue("@CategoryID", (object) categoyid); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - topicInfoList.Add(new TopicInfo() - { - TopicID = sqLiteDataReader.GetInt32(0), - CategoryID = sqLiteDataReader.GetInt32(1), - Name2 = sqLiteDataReader.GetString(2), - Hash = sqLiteDataReader.GetString(3), - Size = sqLiteDataReader.GetInt64(4), - Seeders = sqLiteDataReader.GetInt32(5), - Status = sqLiteDataReader.GetInt32(6), - IsKeep = sqLiteDataReader.GetBoolean(9), - IsKeeper = sqLiteDataReader.GetBoolean(10), - IsBlackList = sqLiteDataReader.GetBoolean(11), - IsDownload = sqLiteDataReader.GetBoolean(12), - AvgSeeders = sqLiteDataReader.IsDBNull(13) ? new Decimal?() : new Decimal?(sqLiteDataReader.GetDecimal(13)), - RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), - PosterID = sqLiteDataReader.IsDBNull(15) ? 0 : sqLiteDataReader.GetInt32(15) - }); - } - } - return topicInfoList; - } - - public List GetTopicsAllByCategory(int categoyid) - { - DateTime dateTime = new DateTime(2000, 1, 1); - List topicInfoList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "SELECT TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, PosterID\r\nFROM Topic WHERE (CategoryID = @CategoryID OR @CategoryID = -1) and Hash is null"; - command.Parameters.AddWithValue("@CategoryID", (object) categoyid); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - topicInfoList.Add(new TopicInfo() - { - TopicID = sqLiteDataReader.GetInt32(0), - CategoryID = sqLiteDataReader.GetInt32(1), - Name2 = sqLiteDataReader.GetString(2), - Hash = sqLiteDataReader.GetString(3), - Size = sqLiteDataReader.GetInt64(4), - Seeders = sqLiteDataReader.GetInt32(5), - Status = sqLiteDataReader.GetInt32(6), - IsKeep = sqLiteDataReader.GetBoolean(9), - IsKeeper = sqLiteDataReader.GetBoolean(10), - IsBlackList = sqLiteDataReader.GetBoolean(11), - IsDownload = sqLiteDataReader.GetBoolean(12), - AvgSeeders = sqLiteDataReader.IsDBNull(13) ? new Decimal?() : new Decimal?(sqLiteDataReader.GetDecimal(13)), - RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), - PosterID = sqLiteDataReader.IsDBNull(15) ? 0 : sqLiteDataReader.GetInt32(15) - }); - } - } - return topicInfoList; - } - - public List GetTopics(DateTime regTime, int categoyid, int? countSeeders, int? avgCountSeeders, bool? isKeep, bool? isKeepers, bool? isDownload, bool? isBlack, bool? isPoster) - { - DateTime dateTime = new DateTime(2000, 1, 1); - List topicInfoList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = @" -SELECT t.TopicID, t.CategoryID, t.Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, CAST(CASE WHEN @UserName = u.Name THEN 1 ELSE 0 END AS BIT), -COUNT(kt.TopicID) AS KeepersCount -FROM Topic AS t -LEFT JOIN User AS u ON (t.PosterID = u.UserID) -LEFT JOIN KeeperToTopic AS kt ON (kt.TopicID = t.TopicID AND kt.KeeperName <> @UserName) -WHERE - t.CategoryID = @CategoryID - AND t.RegTime < @RegTime - AND Status NOT IN (7,4,11,5) -" + ( - countSeeders.HasValue - ? string.Format(" AND Seeders {1} {0}", (object) countSeeders.Value, - Settings.Current.IsSelectLessOrEqual ? (object) " <= " : (object) " = ") - : "" - ) - + (avgCountSeeders.HasValue - ? string.Format(" AND AvgSeeders {1} {0}", (object) avgCountSeeders.Value, - Settings.Current.IsSelectLessOrEqual ? (object) " <= " : (object) " = ") - : "") - + (isKeep.HasValue ? string.Format(" AND IsKeep = {0}", (object) (isKeep.Value ? 1 : 0)) : "") - + (isKeepers.HasValue - ? string.Format(" AND CAST(CASE WHEN kt.TopicID IS NOT NULL THEN 1 ELSE 0 END AS BIT) = {0}", - (object) (isKeepers.Value ? 1 : 0)) - : "") - + (isDownload.HasValue ? string.Format(" AND IsDownload = {0}", (object) (isDownload.Value ? 1 : 0)) : "") - + (isPoster.HasValue ? string.Format(" AND @UserName = u.Name", (object) (isPoster.Value ? 1 : 0)) : "") - + string.Format(" AND IsBlackList = {0}", (object) (!isBlack.HasValue || !isBlack.Value ? 0 : 1)) - + " AND IsDeleted = 0 GROUP BY t.TopicID HAVING t.TopicID IS NOT NULL ORDER BY t.Seeders, t.Name"; - command.Parameters.AddWithValue("@CategoryID", (object) categoyid); - command.Parameters.AddWithValue("@RegTime", (object) regTime); - command.Parameters.AddWithValue("@UserName", string.IsNullOrWhiteSpace(Settings.Current.KeeperName) ? (object) "-" : (object) Settings.Current.KeeperName); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - topicInfoList.Add(new TopicInfo() - { - TopicID = sqLiteDataReader.GetInt32(0), - CategoryID = sqLiteDataReader.GetInt32(1), - Name2 = sqLiteDataReader.IsDBNull(2) ? string.Empty : sqLiteDataReader.GetString(2), - Hash = sqLiteDataReader.IsDBNull(3) ? string.Empty : sqLiteDataReader.GetString(3), - Size = sqLiteDataReader.GetInt64(4), - Seeders = sqLiteDataReader.GetInt32(5), - Status = sqLiteDataReader.GetInt32(6), - IsKeep = sqLiteDataReader.GetBoolean(9), - KeeperCount = sqLiteDataReader.GetInt32(16), - IsBlackList = sqLiteDataReader.GetBoolean(11), - IsDownload = sqLiteDataReader.GetBoolean(12), - AvgSeeders = sqLiteDataReader.IsDBNull(13) ? new Decimal?() : new Decimal?(Math.Round(sqLiteDataReader.GetDecimal(13), 3)), - RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), - IsPoster = sqLiteDataReader.GetBoolean(15) - }); - } - } - return topicInfoList; - } - - public void SetTorrentClientHash(List data) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "UPDATE Topic SET IsDownload = @IsDownload, IsKeep = @IsKeep WHERE Hash = @Hash;"; - foreach (TopicInfo topicInfo in data) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@Hash", (object) topicInfo.Hash); - command.Parameters.AddWithValue("@IsDownload", (object) topicInfo.IsDownload); - command.Parameters.AddWithValue("@IsKeep", (object) topicInfo.IsKeep); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public void SaveTorrentClients(IEnumerable data, bool isUpdateList = false) - { - List tc = this.GetTorrentClients(); - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - if (isUpdateList) - { - command.CommandText = "DELETE FROM TorrentClient WHERE UID = @UID"; - List source = tc; - foreach (TorrentClientInfo torrentClientInfo in source.Where((Func) (x => !data.Select((Func) (y => y.UID)).Contains(x.UID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@UID", (object) torrentClientInfo.UID.ToString()); - command.ExecuteNonQuery(); - } - } - command.CommandText = "UPDATE TorrentClient SET Name = @Name, Type = @Type, ServerName = @ServerName, ServerPort = @ServerPort, UserName = @UserName, UserPassword = @UserPassword, LastReadHash = @LastReadHash WHERE UID = @UID"; - IEnumerable source1 = data; - foreach (TorrentClientInfo torrentClientInfo in source1.Where((Func) (x => tc.Select((Func) (y => y.UID)).Contains(x.UID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@UID", (object) torrentClientInfo.UID.ToString()); - command.Parameters.AddWithValue("@Name", (object) torrentClientInfo.Name); - command.Parameters.AddWithValue("@Type", (object) torrentClientInfo.Type); - command.Parameters.AddWithValue("@ServerName", (object) torrentClientInfo.ServerName); - command.Parameters.AddWithValue("@ServerPort", (object) torrentClientInfo.ServerPort); - command.Parameters.AddWithValue("@UserName", (object) torrentClientInfo.UserName); - command.Parameters.AddWithValue("@UserPassword", (object) torrentClientInfo.UserPassword); - command.Parameters.AddWithValue("@LastReadHash", (object) torrentClientInfo.LastReadHash); - command.ExecuteNonQuery(); - } - command.CommandText = "INSERT INTO TorrentClient (UID, Name, Type, ServerName, ServerPort, UserName, UserPassword, LastReadHash) VALUES(@UID, @Name, @Type, @ServerName, @ServerPort, @UserName, @UserPassword, @LastReadHash)"; - IEnumerable source2 = data; - foreach (TorrentClientInfo torrentClientInfo in source2.Where((Func) (x => !tc.Select((Func) (y => y.UID)).Contains(x.UID)))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@UID", (object) torrentClientInfo.UID.ToString()); - command.Parameters.AddWithValue("@Name", (object) torrentClientInfo.Name); - command.Parameters.AddWithValue("@Type", (object) torrentClientInfo.Type); - command.Parameters.AddWithValue("@ServerName", (object) torrentClientInfo.ServerName); - command.Parameters.AddWithValue("@ServerPort", (object) torrentClientInfo.ServerPort); - command.Parameters.AddWithValue("@UserName", (object) torrentClientInfo.UserName); - command.Parameters.AddWithValue("@UserPassword", (object) torrentClientInfo.UserPassword); - command.Parameters.AddWithValue("@LastReadHash", (object) torrentClientInfo.LastReadHash); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public List GetTorrentClients() - { - List torrentClientInfoList = new List(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "SELECT * FROM TorrentClient"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - torrentClientInfoList.Add(new TorrentClientInfo() - { - UID = Guid.Parse(sqLiteDataReader.GetString(0)), - Name = sqLiteDataReader.GetString(1), - Type = sqLiteDataReader.GetString(2), - ServerName = sqLiteDataReader.GetString(3), - ServerPort = sqLiteDataReader.GetInt32(4), - UserName = sqLiteDataReader.GetString(5), - UserPassword = sqLiteDataReader.GetString(6), - LastReadHash = sqLiteDataReader.GetDateTime(7) - }); - } - } - return torrentClientInfoList; - } - - public void SaveKeepOtherKeepers(Dictionary>> data) - { - if (data == null) - return; - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandTimeout = 60000; - foreach (KeyValuePair>> keyValuePair in data) - { - KeyValuePair>> dt = keyValuePair; - int[] array = dt.Value.Item2.Distinct().ToArray(); - List[] intListArray = new List[array.Length % 500 == 0 ? array.Length / 500 : array.Length / 500 + 1]; - for (int index1 = 0; index1 < array.Length; ++index1) - { - int index2 = index1 / 500; - if (intListArray[index2] == null) - intListArray[index2] = new List(); - intListArray[index2].Add(array[index1]); - } - foreach (List source in intListArray) - { - command.Parameters.Clear(); - command.CommandText = "INSERT OR REPLACE INTO KeeperToTopic(KeeperName, CategoryID, TopicID)\r\n" + string.Join("UNION ", source.Select((Func) (x => string.Format("SELECT @KeeperName, {2}, {1}\r\n", (object) dt.Key, (object) x, (object) dt.Value.Item1)))); - command.Parameters.AddWithValue("@KeeperName", (object) dt.Key.Replace("", "").Trim()); - command.ExecuteNonQuery(); - } - } - } - sqLiteTransaction.Commit(); - } - } - - private void SaveKeepStatus(string keepName, List> data) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "INSERT OR REPLACE INTO Keeper VALUES(@KeeperName, @CategoryID, @Count, @Size)"; - command.Parameters.Add("@KeeperName", DbType.String); - command.Parameters.Add("@CategoryID", DbType.Int32); - command.Parameters.Add("@Count", DbType.Int64); - command.Parameters.Add("@Size", DbType.Decimal); - if (string.IsNullOrWhiteSpace(keepName)) - keepName = Settings.Current.KeeperName; - if (string.IsNullOrWhiteSpace(keepName)) - return; - foreach (Tuple tuple in data) - { - command.Parameters[0].Value = (object) keepName.Replace("", "").Trim(); - command.Parameters[1].Value = (object) tuple.Item1; - command.Parameters[2].Value = (object) tuple.Item2; - command.Parameters[3].Value = (object) Math.Round(tuple.Item3, 2); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public void ClearReports() - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "UPDATE Report SET Report = @Report WHERE ReportNo <> 0"; - command.Parameters.AddWithValue("@Report", (object) "Удалено"); - command.ExecuteNonQuery(); - } - sqLiteTransaction.Commit(); - } - } - - public List> GetStatisticsByAllUsers() - { - List> tupleList = new List>(); - bool flag = this.GetTorrentClients().Any(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "INSERT OR REPLACE INTO Keeper SELECT 'All', CategoryID, COUNT(*) Cnt, SUM(Size) / 1073741824.0 Size FROM Topic WHERE IsDeleted = 0 AND CategoryID <> 0 GROUP BY CategoryID;\r\nINSERT OR REPLACE INTO Keeper SELECT kt.KeeperName, kt.CategoryID, COUNT(*), CAST(SUM(t.Size) / 1073741824.0 AS NUMERIC(18,4)) Size \r\n FROM KeeperToTopic AS kt JOIN Topic AS t ON (kt.TopicID = t.TopicID AND kt.KeeperName <> @KeeperName) group by kt.KeeperName, kt.CategoryID;\r\nINSERT OR REPLACE INTO Keeper SELECT @KeeperName, CategoryID, COUNT(*) Cnt, CAST(SUM(Size) / 1073741824.0 AS NUMERIC(18,4)) Size FROM Topic \r\n WHERE IsDeleted = 0 AND IsKeep = 1 AND (Seeders <= @Seeders OR @Seeders = -1) AND Status NOT IN (7, 4,11,5) AND IsBlackList = 0 GROUP BY CategoryID;\r\n"; - command.Parameters.AddWithValue("@KeeperName", flag ? (object) Settings.Current.KeeperName : (object) ""); - command.Parameters.AddWithValue("@Seeders", (object) Settings.Current.CountSeedersReport); - command.ExecuteNonQuery(); - command.CommandText = "SELECT KeeperName, CategoryID, Count, Size FROM Keeper"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - tupleList.Add(new Tuple(sqLiteDataReader.GetInt32(1), sqLiteDataReader.GetString(0), sqLiteDataReader.GetInt32(2), Math.Round(sqLiteDataReader.GetDecimal(3), 3))); - } - } - return tupleList; - } - - public void SaveReports(Dictionary> reports) - { - foreach (KeyValuePair> report in reports) - { - int num = report.Value.Keys.Max((Func) (x => x)); - report.Value.Add(num + 1, "Резерв"); - report.Value.Add(num + 2, "Резерв"); - } - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - Dictionary, Tuple> reps = this.GetReports(new int?()); - if (reports.Any>>((Func>, bool>) (x => !x.Value.ContainsKey(0)))) - { - command.CommandText = "UPDATE Report SET Report = @Report WHERE CategoryID = @CategoryID AND ReportNo <> 0"; - foreach (KeyValuePair> report in reports) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@CategoryID", (object) report.Key); - command.Parameters.AddWithValue("@Report", (object) "Резерв"); - command.ExecuteNonQuery(); - } - } - command.CommandText = "UPDATE Report SET Report = @Report WHERE CategoryID = @CategoryID AND ReportNo = @ReportNo"; - foreach (KeyValuePair> report in reports) - { - KeyValuePair> r1 = report; - Dictionary source = r1.Value; - foreach (KeyValuePair keyValuePair in source.Where>((Func, bool>) (x => reps.ContainsKey(new Tuple(r1.Key, x.Key))))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@CategoryID", (object) r1.Key); - command.Parameters.AddWithValue("@ReportNo", (object) keyValuePair.Key); - command.Parameters.AddWithValue("@Report", (object) keyValuePair.Value); - command.ExecuteNonQuery(); - } - } - command.CommandText = "INSERT OR REPLACE INTO Report VALUES(@CategoryID, @ReportNo, @URL, @Report)"; - foreach (KeyValuePair> report in reports) - { - KeyValuePair> r1 = report; - Dictionary source = r1.Value; - foreach (KeyValuePair keyValuePair in source.Where>((Func, bool>) (x => !reps.ContainsKey(new Tuple(r1.Key, x.Key))))) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@CategoryID", (object) r1.Key); - command.Parameters.AddWithValue("@ReportNo", (object) keyValuePair.Key); - command.Parameters.AddWithValue("@URL", (object) string.Empty); - command.Parameters.AddWithValue("@Report", (object) keyValuePair.Value); - command.ExecuteNonQuery(); - } - } - } - sqLiteTransaction.Commit(); - } - } - - public Dictionary, Tuple> GetReports(int? categoryID = null) - { - Dictionary, Tuple> dictionary = new Dictionary, Tuple>(); - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "SELECT * FROM Report"; - if (categoryID.HasValue) - { - command.CommandText += " WHERE CategoryID = @CategoryID"; - command.Parameters.AddWithValue("@CategoryID", (object) categoryID.Value); - } - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - { - if (!dictionary.ContainsKey(new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetInt32(1)))) - dictionary.Add(new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetInt32(1)), new Tuple(sqLiteDataReader.GetString(2), sqLiteDataReader.GetString(3))); - } - } - } - return dictionary; - } - - public void SaveSettingsReport(List> result) - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - command.CommandText = "SELECT DISTINCT CategoryID FROM Report WHERE ReportNo = 0"; - HashSet filter = new HashSet(); - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - filter.Add(sqLiteDataReader.GetInt32(0)); - } - command.CommandText = "UPDATE Report SET URL = @url WHERE CategoryID = @CategoryID AND ReportNo = @ReportNo"; - command.Parameters.Add("@CategoryID", DbType.Int32); - command.Parameters.Add("@ReportNo", DbType.Int32); - command.Parameters.Add("@url", DbType.String); - command.Prepare(); - foreach (Tuple tuple in result) - { - command.Parameters["@CategoryID"].Value = (object) tuple.Item1; - command.Parameters["@ReportNo"].Value = (object) tuple.Item2; - command.Parameters["@url"].Value = (object) tuple.Item3; - command.ExecuteNonQuery(); - } - command.CommandText = "INSERT OR REPLACE INTO Report VALUES(@CategoryID, @ReportNo, @URL, '')"; - command.Prepare(); - List> source = result; - foreach (Tuple tuple in source.Where>((Func, bool>) (x => !filter.Contains(x.Item1)))) - { - command.Parameters["@CategoryID"].Value = (object) tuple.Item1; - command.Parameters["@ReportNo"].Value = (object) tuple.Item2; - command.Parameters["@url"].Value = (object) tuple.Item3; - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public void UpdateStatistics() - { - using (SQLiteTransaction sqLiteTransaction = this._conn.BeginTransaction()) - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.Transaction = sqLiteTransaction; - List numArrayList = new List(); - command.CommandText = "update Topic SET AvgSeeders = (SELECT AVG(Seeders) FROM TopicStatusHystory AS st WHERE st.TopicID = Topic.TopicID)"; - command.ExecuteNonQuery(); - command.CommandText = "UPDATE Topic SET AvgSeeders = @Seeders WHERE TopicID = @TopicID"; - foreach (Decimal[] numArray in numArrayList) - { - command.Parameters.Clear(); - command.Parameters.AddWithValue("@TopicID", (object) numArray[0]); - command.Parameters.AddWithValue("@Seeders", (object) numArray[1]); - command.ExecuteNonQuery(); - } - } - sqLiteTransaction.Commit(); - } - } - - public void ClearKeepers() - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - command.CommandText = "DELETE FROM Keeper;\r\nDELETE FROM KeeperToTopic;\r\nUPDATE Report SET Report = '' WHERE ReportNo = 0"; - command.ExecuteNonQuery(); - } - } - - public void CreateReportByRootCategories() - { - try - { - using (SQLiteCommand command = this._conn.CreateCommand()) - { - this.GetStatisticsByAllUsers(); - Dictionary> reports = new Dictionary>(); - Dictionary> source1 = new Dictionary>(); - Dictionary, Tuple> dictionary1 = new Dictionary, Tuple>(); - Dictionary, Tuple> dictionary2 = new Dictionary, Tuple>(); - List> tupleList = new List>(); - command.CommandText = "\r\nSELECT c.CategoryID, c.FullName, SUM(Count)Count, SUM(Size)Size\r\nFROM\r\n (\r\n SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION\r\n SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 \r\n ) AS t \r\n JOIN Category AS c ON (t.ParentID = c.CategoryID) \r\n JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All')\r\nGROUP BY\r\n c.CategoryID, c.FullName\r\nORDER BY c.FullName"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - source1.Add(sqLiteDataReader.GetInt32(0), new Tuple(sqLiteDataReader.GetString(1), sqLiteDataReader.GetDecimal(2), sqLiteDataReader.GetDecimal(3))); - } - command.CommandText = "\r\nSELECT c.CategoryID, c.FullName, k.KeeperName, SUM(Count)Count, SUM(Size)Size\r\nFROM\r\n (\r\n SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION\r\n SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 \r\n ) AS t \r\n JOIN Category AS c ON (t.ParentID = c.CategoryID) \r\n JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All')\r\nGROUP BY\r\n c.CategoryID, c.FullName, k.KeeperName\r\nORDER BY c.FullName, k.KeeperName"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - dictionary1.Add(new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetString(2)), new Tuple(sqLiteDataReader.GetString(1), sqLiteDataReader.GetDecimal(3), sqLiteDataReader.GetDecimal(4))); - } - command.CommandText = "\r\nSELECT t.ParentID, c.CategoryID, c.FullName, k.KeeperName, SUM(Count)Count, SUM(Size)Size\r\nFROM\r\n (\r\n SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION\r\n SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 \r\n ) AS t \r\n JOIN Category AS c ON (t.CategoryID = c.CategoryID) \r\n JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All')\r\nGROUP BY\r\n t.ParentID, c.FullName, k.KeeperName, c.CategoryID\r\nORDER BY c.FullName, k.KeeperName"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - dictionary2.Add(new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetString(3), sqLiteDataReader.GetInt32(1)), new Tuple(sqLiteDataReader.GetString(2), sqLiteDataReader.GetDecimal(4), sqLiteDataReader.GetDecimal(5))); - } - command.CommandText = "\r\nSELECT t.ParentID, c.CategoryID, c.FullName,SUM(Count)Count, SUM(Size)Size\r\nFROM\r\n (\r\n SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION\r\n SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 \r\n ) AS t \r\n JOIN Category AS c ON (t.CategoryID = c.CategoryID) \r\n JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All')\r\nGROUP BY\r\n c.CategoryID, c.FullName\r\nORDER BY c.FullName"; - using (SQLiteDataReader sqLiteDataReader = command.ExecuteReader()) - { - while (sqLiteDataReader.Read()) - tupleList.Add(new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetInt32(1), sqLiteDataReader.GetString(2), sqLiteDataReader.GetDecimal(3), sqLiteDataReader.GetDecimal(4))); - } - foreach (int num1 in source1.Select>, int>((Func>, int>) (x => x.Key))) - { - int c = num1; - StringBuilder stringBuilder1 = new StringBuilder(); - StringBuilder stringBuilder2 = stringBuilder1; - string format = "[hr]\r\n[hr]\r\n[b][color=darkgreen][align=center][size=16]Статистика раздела: {0}[/size][/align][/color][/b][hr]\r\n[hr]\r\n\r\n"; - DateTime dateTime = DateTime.Now; - dateTime = dateTime.Date; - string str = dateTime.ToString("dd.MM.yyyy"); - stringBuilder2.AppendFormat(format, (object) str); - stringBuilder1.AppendFormat("Всего: {0} шт. ({1:0.00} Гб.)\r\n\r\n", (object) source1[c].Item2, (object) source1[c].Item3); - stringBuilder1.AppendLine("[hr]"); - stringBuilder1.AppendLine("[size=12][b]По хранителям:[/b][/size]"); - int num2 = 1; - Dictionary, Tuple> source2 = dictionary1; - foreach (KeyValuePair, Tuple> keyValuePair1 in source2.Where, Tuple>>((Func, Tuple>, bool>) (x => x.Key.Item1 == c))) - { - KeyValuePair, Tuple> k = keyValuePair1; - stringBuilder1.AppendFormat("[spoiler=\"{0}. {1} - {2} шт. ({3:0.00} Гб.)\"]\r\n", (object) num2, (object) k.Key.Item2, (object) k.Value.Item2, (object) k.Value.Item3); - Dictionary, Tuple> source3 = dictionary2; - foreach (KeyValuePair, Tuple> keyValuePair2 in source3.Where, Tuple>>((Func, Tuple>, bool>) (x => - { - if (x.Key.Item2 == k.Key.Item2) - return x.Key.Item1 == c; - return false; - }))) - stringBuilder1.AppendFormat("{0} - {1} шт. ({2:0.00} Гб.)\r\n", (object) keyValuePair2.Value.Item1, (object) keyValuePair2.Value.Item2, (object) keyValuePair2.Value.Item3); - stringBuilder1.AppendLine("[/spoiler]"); - ++num2; - } - stringBuilder1.AppendLine("[hr]"); - stringBuilder1.AppendLine("[size=12][b]По форумам:[/b][/size]"); - List> source4 = tupleList; - foreach (Tuple tuple in (IEnumerable>) source4.Where>((Func, bool>) (x => x.Item1 == c)).OrderBy, string>((Func, string>) (x => x.Item3))) - { - Tuple k = tuple; - stringBuilder1.AppendFormat("[spoiler=\"{0} - {1} шт. ({2:0.00} Гб.)\"]\r\n", (object) k.Item3, (object) k.Item4, (object) k.Item5); - Dictionary, Tuple> source3 = dictionary2; - foreach (KeyValuePair, Tuple> keyValuePair in (IEnumerable, Tuple>>) source3.Where, Tuple>>((Func, Tuple>, bool>) (x => x.Key.Item3 == k.Item2)).OrderBy, Tuple>, string>((Func, Tuple>, string>) (x => x.Key.Item2))) - stringBuilder1.AppendFormat("{0} - {1} шт. ({2:0.00} Гб.)\r\n", (object) keyValuePair.Key.Item2, (object) keyValuePair.Value.Item2, (object) keyValuePair.Value.Item3); - stringBuilder1.AppendLine("[/spoiler]"); - } - reports.Add(c, new Dictionary()); - reports[c].Add(0, stringBuilder1.ToString().Replace("", "").Trim()); - } - this.SaveReports(reports); - } - } - catch (Exception ex) - { - } - } - } -} diff --git a/Clients/DBConnectionCreator.cs b/Clients/DBConnectionCreator.cs deleted file mode 100644 index 3536a4a..0000000 --- a/Clients/DBConnectionCreator.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Data.SQLite; -using NLog; -using TLO.local.Forms; - -namespace TLO.local -{ - public class DBConnectionCreator - { - public SQLiteConnection Connection { get; } - - private static Logger _logger { get; set; } - - string FileDatabase => System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "Database.db"); - - public DBConnectionCreator() - { - if (_logger == null) - _logger = LogManager.GetLogger("ClientServer"); - - var db = $"Data Source={FileDatabase};Version=3;"; - if (InMemory()) - { - SQLiteConnection tmpConnection = new SQLiteConnection(db); - tmpConnection.Open(); - Connection = new SQLiteConnection("Data Source=:memory:;Version=3;"); - Connection.Open(); - _logger.Info("Загрузка базы в память..."); - tmpConnection.BackupDatabase(Connection, "main", "main", -1, null, -1); - tmpConnection.Close(); - _logger.Info("Загрузка базы в память завершена."); - } - else - { - _logger.Info("Подключение к файлу бд..."); - Connection = new SQLiteConnection(db); - Connection.Open(); - } - } - - public void Close() - { - Connection.Close(); - } - - public static bool InMemory() - { - return Settings.Current.LoadDBInMemory.GetValueOrDefault(true); - } - } -} diff --git a/Clients/ITorrentClient.cs b/Clients/ITorrentClient.cs deleted file mode 100644 index 80d2ba9..0000000 --- a/Clients/ITorrentClient.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.ITorrentClient -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System.Collections.Generic; - -namespace TLO.local -{ - internal interface ITorrentClient - { - List GetAllTorrentHash(); - - IEnumerable GetFiles(TopicInfo topic); - - void DistributionStop(IEnumerable data); - - void DistributionPause(IEnumerable data); - - void DistributionStart(IEnumerable data); - - bool Ping(); - - bool SetDefaultFolder(string dir); - - bool SetDefaultLabel(string label); - - string GetDefaultFolder(); - - void SendTorrentFile(string path, string file); - - void SendTorrentFile(string path, string filename, byte[] fdata); - - string[] GetTrackers(string hash); - - bool SetTrackers(string hash, string[] trackers); - - bool SetLabel(string hash, string label); - - bool SetLabel(IEnumerable hash, string label); - } -} diff --git a/Clients/KTorrentClient.cs b/Clients/KTorrentClient.cs deleted file mode 100644 index 0cd3c8c..0000000 --- a/Clients/KTorrentClient.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.KTorrentClient -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Collections.Generic; -using System.Text; - -namespace TLO.local -{ - internal class KTorrentClient : ITorrentClient - { - private static Logger _logger; - private TLOWebClient _webClient; - private string _ServerName; - private int _ServerPort; - private string svcCredentials; - - public KTorrentClient(string serverName, int port, string userName, string userPass) - { - if (KTorrentClient._logger == null) - KTorrentClient._logger = LogManager.GetLogger("TransmissionClient"); - this._webClient = new TLOWebClient(Encoding.UTF8, "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0", "application/json, text/javascript, */*; q=0.01", true); - this._webClient.Encoding = Encoding.UTF8; - this.svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + userPass)); - this._webClient.Headers.Add("Authorization", "Basic " + this.svcCredentials); - this._ServerName = serverName; - this._ServerPort = port; - try - { - this.Ping(); - } - catch - { - KTorrentClient._logger.Debug(string.Format("Имя сервера: {0}; Порт сервера: {1}", (object) serverName, (object) port)); - throw; - } - } - - public List GetAllTorrentHash() - { - return new List(); - } - - public IEnumerable GetFiles(TopicInfo topic) - { - return (IEnumerable) new List(); - } - - public void DistributionStop(IEnumerable data) - { - } - - public void DistributionPause(IEnumerable data) - { - } - - public void DistributionStart(IEnumerable data) - { - } - - public bool Ping() - { - return true; - } - - public bool SetDefaultFolder(string dir) - { - return true; - } - - public bool SetDefaultLabel(string label) - { - return true; - } - - public string GetDefaultFolder() - { - return string.Empty; - } - - public void SendTorrentFile(string path, string file) - { - } - - public void SendTorrentFile(string path, string filename, byte[] fdata) - { - } - - public string[] GetTrackers(string hash) - { - return (string[]) null; - } - - public bool SetTrackers(string hash, string[] trackers) - { - return true; - } - - public bool SetLabel(string hash, string label) - { - return true; - } - - public bool SetLabel(IEnumerable hash, string label) - { - return true; - } - } -} diff --git a/Clients/RuTrackerOrg.cs b/Clients/RuTrackerOrg.cs deleted file mode 100644 index c480215..0000000 --- a/Clients/RuTrackerOrg.cs +++ /dev/null @@ -1,747 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.RuTrackerOrg -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Drawing.Printing; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Web; -using System.Windows.Forms; - -namespace TLO.local -{ - internal class RuTrackerOrg - { - private Logger _logger; - private TLOWebClient _webClient; - private string _userName; - private string _userPass; - private int _keeperid; - private string _apiid; - private JsonSerializer jSerializer; - private static RuTrackerOrg _current; - - public static RuTrackerOrg Current - { - get - { - if (RuTrackerOrg._current == null) - RuTrackerOrg._current = new RuTrackerOrg(); - return RuTrackerOrg._current; - } - } - - private RuTrackerOrg() - : this((string) null, (string) null) - { - } - - public RuTrackerOrg(string userName, string password) - { - this.jSerializer = new JsonSerializer(); - this._userName = userName; - this._userPass = password; - if (this._logger == null) - this._logger = LogManager.GetLogger("RuTrackerOrg"); - if (string.IsNullOrWhiteSpace(this._userName) || string.IsNullOrWhiteSpace(this._userPass)) - return; - this.ReadKeeperInfo(); - } - - public IEnumerable GetCategories() - { - List source = new List(); - var downloadArchivePage = this.DownloadArchivePage($"http://api.{Settings.Current.HostRuTrackerOrg}/v1/static/cat_forum_tree"); - JObject jobject1 = (JsonConvert.DeserializeObject(downloadArchivePage) as JObject)["result"].ToObject(); - jobject1["c"].ToObject(); - source.AddRange((IEnumerable) jobject1["c"].ToObject>().Select, Category>((Func, Category>) (x => new Category() - { - CategoryID = 1000000 + int.Parse(x.Key), - Name = x.Value as string - })).ToArray()); - source.AddRange(jobject1["f"].ToObject>().Select, Category>((Func, Category>) (x => new Category() - { - CategoryID = int.Parse(x.Key), - Name = x.Value as string - }))); - Dictionary dictionary = source.ToDictionary((Func) (x => x.CategoryID), (Func) (x => x)); - JObject jobject2 = jobject1["tree"].ToObject(); - int num = 0; - foreach (KeyValuePair keyValuePair1 in jobject2) - { - int key1 = int.Parse(keyValuePair1.Key) + 1000000; - ++num; - dictionary[key1].OrderID = num; - dictionary[key1].FullName = dictionary[key1].Name; - if (!(keyValuePair1.Value is JObject) || !keyValuePair1.Value.Any()) - { - continue; - } - foreach (KeyValuePair keyValuePair2 in keyValuePair1.Value.ToObject()) - { - int key2 = int.Parse(keyValuePair2.Key); - ++num; - if (dictionary.ContainsKey(key2)) - { - Category category = dictionary[key2]; - category.ParentID = key1; - category.OrderID = num; - category.FullName = string.Format("{0} » {1}", dictionary.ContainsKey(key1) ? (object) dictionary[key1].Name : (object) "", (object) category.Name); - } - foreach (JToken jtoken in keyValuePair2.Value.ToObject()) - { - int key3 = (int) jtoken; - ++num; - if (dictionary.ContainsKey(key3)) - { - Category category = dictionary[key3]; - category.ParentID = key2; - category.OrderID = num; - category.FullName = string.Format("{0} » {1}", dictionary.ContainsKey(key2) ? (object) dictionary[key2].FullName : (object) "", (object) category.Name); - } - } - } - } - return (IEnumerable) source; - } - - public IEnumerable> GetCategoriesFromPost(string postUrl) - { - List> tupleList = new List>(); - string[] array = ((IEnumerable) this.DownloadWebPage(postUrl).Split(new char[2] - { - '\r', - '\n' - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => - { - if (x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=")) - return x.Contains("class=\"postLink\""); - return false; - })).ToArray(); - int? nullable1 = new int?(); - string str1 = (string) null; - HashSet intSet = new HashSet(); - foreach (string str2 in array) - { - char[] separator = new char[4]{ '"', '<', '>', ' ' }; - int num1 = 1; - foreach (string postUrl1 in ((IEnumerable) str2.Split(separator, (StringSplitOptions) num1)).Where((Func) (x => - { - if (!x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=") && !x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) - return x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p="); - return true; - })).ToArray()) - { - if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=")) - nullable1 = new int?(int.Parse(postUrl1.Replace($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=", ""))); - int? nullable2 = nullable1; - int num2 = 2020; - if ((nullable2.GetValueOrDefault() == num2 ? (nullable2.HasValue ? 1 : 0) : 0) != 0) - Console.Write(""); - if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=") && postUrl1 != $"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=") - str1 = postUrl1; - if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p=")) - str1 = this.GetTopicUrlByPostUrl(postUrl1); - } - if (nullable1.HasValue && !string.IsNullOrWhiteSpace(str1)) - tupleList.Add(new Tuple(nullable1.Value, str1)); - nullable1 = new int?(); - str1 = (string) null; - } - return (IEnumerable>) tupleList; - } - - public string GetTopicUrlByPostUrl(string postUrl) - { - string str = this.DownloadWebPage(postUrl); - if (str.Contains("
Тема не найдена
")) - return (string) null; - return ((IEnumerable) str.Split(new char[1] - { - '"' - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t="))).Select((Func) (x => x)).FirstOrDefault(); - } - - public int[][] GetTopicsStatus(int forumID) - { - Dictionary dictionary = JsonConvert.DeserializeObject(this.DownloadArchivePage(string.Format("http://api.{1}/v1/static/pvc/f/{0}", (object) forumID, Settings.Current.HostRuTrackerOrg)))["result"].ToObject>(); - int[][] numArray1 = new int[dictionary.Count][]; - int index = 0; - foreach (KeyValuePair keyValuePair in dictionary) - { - Int64[] numArray2 = keyValuePair.Value; - numArray1[index] = new int[2] - { - keyValuePair.Key, - numArray2.Length > 1 ? (int)numArray2[1] : -1 - }; - ++index; - } - return numArray1; - } - - public List GetTopicsInfo(int[] topics) - { - if (topics == null || topics.Length == 0 || topics.Length > 100) - return (List) null; - List topicInfoList = new List(); - foreach (KeyValuePair> keyValuePair in JsonConvert.DeserializeObject(this.DownloadArchivePage(string.Format("http://api.{0}/v1/get_tor_topic_data?by=topic_id&val={1}", Settings.Current.HostRuTrackerOrg, (object) HttpUtility.UrlEncode(string.Join(",", (IEnumerable) topics)))))["result"].ToObject>>()) - { - TopicInfo topicInfo = new TopicInfo(); - topicInfo.TopicID = keyValuePair.Key; - Dictionary dictionary = keyValuePair.Value; - if (dictionary != null) - { - topicInfo.Hash = dictionary["info_hash"] as string; - topicInfo.CategoryID = int.Parse(dictionary["forum_id"].ToString()); - topicInfo.RegTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((double) int.Parse(dictionary["reg_time"].ToString())); - topicInfo.Size = long.Parse(dictionary["size"].ToString()); - topicInfo.Status = int.Parse(dictionary["tor_status"].ToString()); - topicInfo.Seeders = int.Parse(dictionary["seeders"].ToString()); - topicInfo.Name2 = dictionary["topic_title"] as string; - topicInfo.PosterID = int.Parse(dictionary["poster_id"].ToString()); - } - topicInfoList.Add(topicInfo); - } - Thread.Sleep(500); - return topicInfoList; - } - - public IEnumerable GetUsers(int[] id) - { - if (id == null || ((IEnumerable) id).Count() == 0) - return (IEnumerable) null; - List userInfoList = new List(); - List[] intListArray = new List[((IEnumerable) id).Count() % 100 == 0 ? ((IEnumerable) id).Count() / 100 : ((IEnumerable) id).Count() / 100 + 1]; - for (int index1 = 0; index1 < ((IEnumerable) id).Count(); ++index1) - { - int index2 = index1 / 100; - if (intListArray[index2] == null) - intListArray[index2] = new List(); - intListArray[index2].Add(id[index1]); - } - foreach (IEnumerable values in intListArray) - { - var url = string.Format("http://api.{0}/v1/get_user_name?by=user_id&val={1}", Settings.Current.HostRuTrackerOrg, (object) HttpUtility.UrlEncode(string.Join(",", values))); - var getUserNameResult = this.DownloadArchivePage(url); - foreach (KeyValuePair keyValuePair in JsonConvert.DeserializeObject(getUserNameResult)["result"].ToObject>()) - userInfoList.Add(new UserInfo() - { - UserID = keyValuePair.Key, - Name = keyValuePair.Value - }); - Thread.Sleep(500); - } - return (IEnumerable) userInfoList; - } - - public List GetPostsFromTopicId(int topicid) - { - string empty = string.Empty; - int num1 = 0; - List intList = new List(); - string str1; - do - { - empty = string.Empty; - str1 = this.DownloadWebPage(string.Format("https://{2}/forum/viewtopic.php?t={0}{1}", (object) topicid, num1 == 0 ? (object) "" : (object) ("&start=" + num1.ToString()), Settings.Current.HostRuTrackerOrg)); - if (str1.Contains("
Тема не найдена
")) - { - Thread.Sleep(500); - str1 = this.DownloadWebPage(string.Format("https://{0}/forum/viewtopic.php?p={1}", (object) topicid, Settings.Current.HostRuTrackerOrg)); - if (str1.Contains("
Тема не найдена
")) - return new List(); - string s = ((IEnumerable) str1.Split(new char[1] - { - '"' - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t="))).Select((Func) (x => x.Replace("https://rutracker.org/forum/viewtopic.php?t=", ""))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(s)) - { - topicid = int.Parse(s); - goto label_13; - } - } - string str2 = str1; - char[] separator1 = new char[2]{ '\r', '\n' }; - int num2 = 1; - foreach (string str3 in ((IEnumerable) str2.Split(separator1, (StringSplitOptions) num2)).Where((Func) (x => x.Contains("\">[Цитировать]"))).ToArray()) - { - char[] separator2 = new char[1]{ '"' }; - int num3 = 1; - string str4 = ((IEnumerable) str3.Split(separator2, (StringSplitOptions) num3)).Where((Func) (x => x.Contains("https://"))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str4)) - { - string[] strArray = str4.Split('='); - if (strArray.Length >= 3) - intList.Add(int.Parse(strArray[2])); - } - } - num1 += 30; -label_13:; - } - while (str1.Contains("\">След.

") || num1 == 0); - return intList; - } - - internal Tuple> GetTopicsFromReport(int postId, int categoryId) - { - Tuple> tuple = (Tuple>) null; - string[] strArray1 = this.DownloadWebPage(string.Format("https://post.{1}/forum/posting.php?mode=quote&p={0}", (object) postId, Settings.Current.HostRuTrackerOrg)).Split(new string[2] - { - "" - }, StringSplitOptions.RemoveEmptyEntries); - if (strArray1.Length < 2) - return tuple; - string str1 = strArray1[1]; - char[] separator = new char[2]{ '[', ']' }; - int num = 1; - foreach (string str2 in ((IEnumerable) str1.Split(separator, (StringSplitOptions) num)).Where((Func) (x => - { - if (!x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) - return x.Contains("quote="); - return true; - })).ToArray()) - { - try - { - if (str2.Contains("quote=")) - tuple = new Tuple>(str2.Replace("quote=", "").Replace("\"", ""), categoryId, new List()); - else if (tuple != null) - { - string[] strArray2 = str2.Split('='); - if (strArray2.Length >= 3) - tuple.Item3.Add(int.Parse(strArray2[2])); - } - } - catch (Exception ex) - { - this._logger.Error("Ошибка получения информации о раздаче по адресу \"" + str2 + "\": " + ex.Message); - } - } - return tuple; - } - - public Dictionary>> GetKeeps(int topicid, int categoryId) - { - Dictionary>> dictionary; - dictionary = new Dictionary>>(); - var empty = string.Empty; - var num = 0; - string str1; - do - { - empty = string.Empty; - str1 = this.DownloadWebPage(string.Format("https://{2}/forum/viewtopic.php?t={0}{1}", - (object) topicid, num == 0 ? (object) "" : (object) ("&start=" + num.ToString()), Settings.Current.HostRuTrackerOrg)); - if (str1.Contains("
Тема не найдена
")) - { - Thread.Sleep(500); - str1 = this.DownloadWebPage( - $"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p={(object) topicid}"); - if (str1.Contains("
Тема не найдена
")) - return dictionary; - var s = ((IEnumerable) string.Join("\r\n", ((IEnumerable) str1.Split(new char[2] - { - '\r', - '\n' - })).Where((Func) (x => x.Contains("id=\"topic-title\"")))).Split(new char[4] - { - '"', - '<', - '>', - ' ' - }, StringSplitOptions.RemoveEmptyEntries)) - .Where((Func) (x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t="))) - .Select((Func) (x => - x.Replace($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=", ""))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(s)) - { - topicid = int.Parse(s); - goto label_18; - } - } - - var array = ((IEnumerable) str1.Split(new char[2] - { - '\r', - '\n' - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => - { - if (x.Contains("\t\t")) - return true; - if (x.Contains("viewtopic.php?t=") && x.Contains("class=\"postLink\"")) - return !x.Contains("(); - var keeperName = string.Empty; - foreach (var str2 in array) - { - if (str2.Contains("\t\t")) - { - keeperName = str2.Replace("\t\t", "").Replace("", "").Replace("", "").Trim(); - } - else - { - if (!dictionary.ContainsKey(keeperName)) - dictionary.Add(keeperName, new Tuple>(categoryId, new List())); - var str3 = ((IEnumerable) str2.Split(new char[6] - { - '"', - '<', - '>', - ' ', - '#', - '&' - }, StringSplitOptions.RemoveEmptyEntries)) - .Where((Func) (x => x.Contains("viewtopic.php?t="))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str3)) - { - var strArray = str3.Split('='); - if (strArray.Length >= 2) - { - try - { - dictionary[keeperName].Item2.Add(int.Parse(strArray[1])); - } - catch (Exception ex) - { - this._logger.Warn(topicid.ToString() + "\t" + strArray[1] + "\t" + ex.Message); - } - } - } - } - } - - num += 30; - label_18: ; - } while (str1.Contains("\">След.

") || num == 0); - - return dictionary; - } - - public Dictionary>> GetKeeps2(int topicid, int categoryId) - { - Dictionary>> dictionary = new Dictionary>>(); - foreach (int postId in this.GetPostsFromTopicId(topicid)) - { - Tuple> topicsFromReport = this.GetTopicsFromReport(postId, categoryId); - if (topicsFromReport != null && topicsFromReport.Item3.Count != 0) - { - if (!dictionary.ContainsKey(topicsFromReport.Item1)) - dictionary.Add(topicsFromReport.Item1, new Tuple>(topicsFromReport.Item2, new List())); - dictionary[topicsFromReport.Item1].Item2.AddRange((IEnumerable) topicsFromReport.Item3); - } - } - return dictionary; - } - - private string DownloadArchivePage(string page) - { - Exception innerException = (Exception) null; - for (int index = 0; index < 20; ++index) - { - string empty = string.Empty; - TLOWebClient tloWebClient = new TLOWebClient(); - try - { - return tloWebClient.DownloadString(page); - } - catch (Exception ex) - { - innerException = ex; - if (ex.Message.Contains("404")) - throw ex; - Thread.Sleep(index * 1000); - } - } - throw new Exception("Не удалось скачать WEB-страницу за 20 попыток: " + innerException.Message, innerException); - } - - public string DownloadWebPage(string page, params object[] param) - { - return Encoding.GetEncoding("windows-1251").GetString(this.DownloadWebPages(string.Format(page, param))); - } - - public byte[] DownloadTorrentFile(int id) - { - for (int index = 0; index < 100; ++index) - { - byte[] numArray1 = new byte[0]; - string empty = string.Empty; - TLOWebClient tloWebClient = (TLOWebClient) null; - try - { - if (this._webClient == null) - { - tloWebClient = new TLOWebClient(); - string s = string.Format("login_username={0}&login_password={1}&login={2}", (object) HttpUtility.UrlEncode(this._userName, Encoding.GetEncoding(1251)), (object) HttpUtility.UrlEncode(this._userPass, Encoding.GetEncoding(1251)), (object) "Вход"); - empty = Encoding.GetEncoding("windows-1251").GetString(tloWebClient.UploadData("https://" + Settings.Current.HostRuTrackerOrg + "/forum/login.php", "POST", Encoding.GetEncoding(1251).GetBytes(s))); - Thread.Sleep(500); - } - } - catch (Exception ex) - { - this._logger.Warn(ex.Message); - this._logger.Warn(ex); - } - if (!string.IsNullOrWhiteSpace(empty)) - { - if (empty.Contains("https://static." + Settings.Current.HostRuTrackerOrg + "/captcha")) - throw new Exception("При авторизации требуется ввести текст с картинки. Авторизуйтесь на WEB-сайте, а потом повторите попытку"); - if (empty.Contains("Регистрация")) - throw new Exception("Не удалось авторизоваться, проверьте логин и пароль"); - this._webClient = tloWebClient; - } - byte[] numArray2; - try - { - if (string.IsNullOrWhiteSpace(this._apiid)) - { - string str = ((IEnumerable) this.DownloadWebPage(string.Format("https://" + Settings.Current.HostRuTrackerOrg + "/forum/viewtopic.php?t={0}", (object) id)).Split(new char[2] - { - '\r', - '\n' - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => x.Contains("form_token: '"))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str)) - str = str.Split(new char[1]{ '\'' }, StringSplitOptions.RemoveEmptyEntries)[1]; - string s = string.Format("form_token={0}", (object) str); - numArray2 = this._webClient.UploadData(string.Format("https://dl." + Settings.Current.HostRuTrackerOrg + "/forum/dl.php?t={0}", (object) id), "POST", Encoding.GetEncoding(1251).GetBytes(s)); - } - else - numArray2 = this._webClient.UploadData("https://" + Settings.Current.HostRuTrackerOrg + "/forum/dl.php", "POST", Encoding.GetEncoding(1251).GetBytes(string.Format("keeper_user_id={0}&keeper_api_key={1}&t={2}&add_retracker_url=0", (object) this._keeperid, (object) this._apiid, (object) id))); - } - catch (Exception ex) - { - if (index >= 20) - throw new Exception("Не удалось скачать WEB-страницу за 20 попыток:" + ex.Message, ex); - Thread.Sleep(index * 1000); - continue; - } - string lower = Encoding.GetEncoding(1251).GetString(numArray2).ToLower(); - if (lower.ToLower().Contains("форум временно отключен") || lower.Contains("форум временно отключен")) - throw new Exception("Форум временно отключен"); - if (lower.Contains("https://static." + Settings.Current.HostRuTrackerOrg + "/captcha") || lower.Contains("регистрация")) - { - if (this._webClient != null) - this._webClient.Dispose(); - this._webClient = (TLOWebClient) null; - } - else - { - if (lower[0] == 'd') - return numArray2; - string path = Path.Combine(Settings.Current.Folder, "error_" + id.ToString() + ".html"); - if (File.Exists(path)) - File.Delete(path); - using (FileStream fileStream = File.Create(path)) - fileStream.Write(numArray2, 0, numArray2.Length); - return (byte[]) null; - } - } - return (byte[]) null; - } - - public byte[] DownloadWebPages(string page) - { - for (int index = 0; index < 20; ++index) - { - string empty = string.Empty; - TLOWebClient tloWebClient = null; - try - { - if (this._webClient == null) - { - tloWebClient = new TLOWebClient(Encoding.GetEncoding(1251)); - if (!string.IsNullOrWhiteSpace(this._userName) && !string.IsNullOrWhiteSpace(this._userPass)) - { - string s = string.Format("login_username={0}&login_password={1}&login={2}", (object) HttpUtility.UrlEncode(this._userName, Encoding.GetEncoding(1251)), (object) HttpUtility.UrlEncode(this._userPass, Encoding.GetEncoding(1251)), (object) "вход"); - empty = Encoding.GetEncoding("windows-1251").GetString(tloWebClient.UploadData($"https://{Settings.Current.HostRuTrackerOrg}/forum/login.php".Replace("rutracker.org", Settings.Current.HostRuTrackerOrg), "POST", Encoding.GetEncoding(1251).GetBytes(s))); - } - Thread.Sleep(500); - } - } - catch (Exception ex) - { - _logger.Warn(ex.Message); - } - if (!string.IsNullOrWhiteSpace(empty) && !string.IsNullOrWhiteSpace(this._userName) && !string.IsNullOrWhiteSpace(this._userPass)) - { - if (empty.Contains($"https://static.{Settings.Current.HostRuTrackerOrg}/captcha".Replace("rutracker.org", Settings.Current.HostRuTrackerOrg))) - throw new Exception("При авторизации требуется ввести текст с картинки. Авторизуйтесь на WEB-сайте, а потом повторите попытку"); - if (empty.Contains("Регистрация")) - throw new Exception("Не удалось авторизоваться, проверьте логин и пароль"); - this._webClient = tloWebClient; - } - byte[] bytes; - try - { - bytes = this._webClient.DownloadData(page); - } - catch(Exception e) - { - _logger.Warn(e.Message); - Thread.Sleep(index * 1000); - continue; - } - string str = Encoding.GetEncoding("windows-1251").GetString(bytes); - if (str.ToLower().Contains("форум временно отключен") || str.ToLower().Contains("форум временно отключен")) - throw new Exception("Форум временно отключен"); - if (!str.Contains($"https://static.{Settings.Current.HostRuTrackerOrg}/captcha".Replace("rutracker.org", Settings.Current.HostRuTrackerOrg)) && !str.Contains("Регистрация")) - return bytes; - if (this._webClient != null) - this._webClient.Dispose(); - this._webClient = (TLOWebClient) null; - } - throw new Exception("Не удалось скачать WEB-страницу за 20 попыток"); - } - - public byte[] DownloadArchiveData(string page) - { - for (int index = 0; index < 20; ++index) - { - byte[] numArray = new byte[0]; - string empty = string.Empty; - if (this._webClient == null) - this._webClient = new TLOWebClient(); - byte[] bytes; - try - { - bytes = this._webClient.DownloadData(page); - } - catch - { - Thread.Sleep(index * 1000); - continue; - } - string lower = Encoding.GetEncoding(1251).GetString(bytes).ToLower(); - if (lower.Contains("введите ваше имя и пароль")) - return new byte[0]; - if (lower.ToLower().Contains("форум временно отключен") || lower.Contains("введите ваше имя и пароль")) - throw new Exception("Форум временно отключен"); - if (lower[0] != 'd') - return new byte[0]; - return bytes; - } - throw new Exception("Не удалось скачать WEB-страницу за 20 попыток"); - } - - public void SavePage(string topicID, string folder) - { - string str = new TLOWebClient().DownloadString(string.Format("https://rutracker.org/forum/viewtopic.php?t={0}", (object) topicID)); - if (str.Contains("Тема не найдена")) - return; - using (FileStream fileStream = File.Create(Path.Combine(folder, string.Format("{0}.html", (object) topicID)))) - { - using (StreamWriter streamWriter = new StreamWriter((Stream) fileStream, Encoding.GetEncoding(1251))) - streamWriter.Write(str); - } - } - - public void SendReport(string url, string message) - { - if (((IEnumerable) url.Split('#')).FirstOrDefault().Split('=').Length < 3) - throw new ArgumentException("Не корректно указан адрес отправки отчета: " + url); - string str1 = ((IEnumerable) url.Split('#')).FirstOrDefault().Split('=')[2]; - string[] strArray = this.DownloadWebPage(string.Format("https://{1}/forum/posting.php?mode=editpost&p={0}", (object) str1, Settings.Current.HostRuTrackerOrg)).Split(new char[2] - { - '\r', - '\n' - }, StringSplitOptions.RemoveEmptyEntries); - Thread.Sleep(1000); - string.Format("align=-1&codeColor=black&codeSize=12&codeUrl2=&decflag=2&f=1584&fontFace=-1&form_token=c2a9bace5d7f3900e2bddbf5f0f0f94a&message=&mode=editpost&p=59972538&submit_mode=submit&t=3985106"); - string str3 = ((IEnumerable) strArray).Where((Func) (x => x.Contains("form_token: '"))).FirstOrDefault(); - if (string.IsNullOrWhiteSpace(str3)) - throw new ArgumentException("Параметр 'form_token' не найден на странице"); - string str4 = ((IEnumerable) strArray).Where((Func) (x => x.Contains("name=\"t\" value=\""))).FirstOrDefault(); - if (string.IsNullOrWhiteSpace(str4)) - throw new ArgumentException("Параметр 't' не найден на странице"); - if (str4.Split('"').Length < 6) - throw new ArgumentException("Массив с параметром 't' меньше предполагаемого: " + str4); - if (str3.Split('\'').Length < 2) - throw new ArgumentException("Массив с параметром 'form_token' меньше предполагаемого: " + str3); - string str5 = ((IEnumerable) strArray).Where((Func) (x => x.Contains("name=\"subject\" "))).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str5)) - { - if (str5.Split('"').Length < 12) - throw new ArgumentException("Массив с параметром 'subject' меньше предполагаемого: " + str5); - } - string format = "mode=editpost&t={0}&p={1}&submit_mode=submit&form_token={3}{4}&message={2}"; - object[] objArray = new object[5] - { - (object) str4.Split('"')[5], - (object) str1, - (object) HttpUtility.UrlEncode(message, Encoding.GetEncoding(1251)), - (object) str3.Split('\'')[1], - null - }; - int index1 = 4; - string str6; - if (!string.IsNullOrWhiteSpace(str5)) - str6 = string.Format("&subject={0}", (object) HttpUtility.UrlEncode(str5.Split('"')[11], Encoding.GetEncoding(1251))); - else - str6 = string.Empty; - objArray[index1] = (object) str6; - string s = string.Format(format, objArray); - for (int index2 = 0; index2 < 20; ++index2) - { - try - { - if (this._webClient == null) - this.DownloadWebPage(string.Format("https://{0}/forum/posting.php?mode=editpost&p={1}", (object) Settings.Current.HostRuTrackerOrg, (object) str1)); - this._webClient.UploadData(string.Format("https://{0}/forum/posting.php?mode=editpost&p={1}", (object) Settings.Current.HostRuTrackerOrg, (object) str1), "POST", Encoding.GetEncoding(1251).GetBytes(s)); - break; - } - catch (Exception ex) - { - if (index2 == 20) - throw new Exception("Не удалось отправить отчет за 10 попыток. Ошибка " + ex.Message); - Thread.Sleep(index2 * 1000); - } - } - Thread.Sleep(1000); - } - - public void ReadKeeperInfo() - { - try - { - string str = ((IEnumerable)this.DownloadWebPage(string.Format("https://{1}/forum/profile.php?mode=viewprofile&u={0}", (object)this._userName, Settings.Current.HostRuTrackerOrg)).Split(new char[2] - { - '\r', - '\n' - })).Where((Func)(x => - { - if (x.Contains("bt:")) - return x.Contains("api:"); - return false; - })).FirstOrDefault(); - if (string.IsNullOrWhiteSpace(str)) - return; - this._apiid = str.Split(new string[2] - { - "", - "" - }, StringSplitOptions.RemoveEmptyEntries)[3]; - this._keeperid = int.Parse(str.Split(new string[2] - { - "", - "" - }, StringSplitOptions.RemoveEmptyEntries)[5]); - } - catch - { - } - this._logger.Info("Результат авторизации: KeeperID: {0}; KeeperApiKey: {1}", this._keeperid, this._apiid); - } - } -} diff --git a/Clients/TLOWebClient.cs b/Clients/TLOWebClient.cs deleted file mode 100644 index 7dc1a01..0000000 --- a/Clients/TLOWebClient.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.TLOWebClient -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Net; -using System.Text; - -namespace TLO.local -{ - internal class TLOWebClient : WebClient - { - private string _UserAgent = string.Empty; - private string _Accept = string.Empty; - private static Logger _logger; - private bool _IsJson; - - public TLOWebClient() - : this((Encoding) null, (string) null, (string) null, false) - { - } - - public TLOWebClient(Encoding encoding) - : this(encoding, (string) null, (string) null, false) - { - } - - public TLOWebClient(Encoding encoding, string userAgent, string accept, bool isJson = false) - { - if (TLOWebClient._logger == null) - TLOWebClient._logger = LogManager.GetCurrentClassLogger(); - Encoding encoding1; - if (encoding != null) - encoding1 = encoding; - else - encoding = encoding1 = Encoding.UTF8; - this.Encoding = encoding1; - this._UserAgent = string.IsNullOrWhiteSpace(userAgent) ? "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0" : userAgent; - this._Accept = string.IsNullOrWhiteSpace(accept) ? "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" : accept; - this.CookieContainer = new CookieContainer(); - this._IsJson = isJson; - } - - public TLOWebClient(string userAgent) - { - this._UserAgent = userAgent; - } - - public CookieContainer CookieContainer { get; private set; } - - protected override WebRequest GetWebRequest(Uri address) - { - HttpWebRequest webRequest = (HttpWebRequest) base.GetWebRequest(address); - webRequest.Accept = this._IsJson ? "application/json" : this._Accept; - webRequest.UserAgent = this._UserAgent; - webRequest.Headers.Add("Accept-Encoding", "gzip, deflate"); - webRequest.Headers.Add("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"); - if (this._IsJson) - { - webRequest.Headers.Add("X-Request", "JSON"); - webRequest.Headers.Add("X-Requested-With", "XMLHttpRequest"); - } - webRequest.ContentType = "application/x-www-form-urlencoded"; - webRequest.KeepAlive = true; - webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; - webRequest.Headers.Add("Pragma", "no-cache"); - webRequest.Timeout = 3600000; - if (address.Host == "dl.rutracker.org" && address.AbsoluteUri.Contains("=")) - { - string[] strArray = address.AbsoluteUri.Split(new char[1] - { - '=' - }, StringSplitOptions.RemoveEmptyEntries); - this.CookieContainer.Add(address, new Cookie("bb_dl", strArray[1])); - webRequest.Referer = string.Format("https://{1}/forum/viewtopic.php?t={0}", (object) strArray[1], Settings.Current.HostRuTrackerOrg); - } - webRequest.CookieContainer = this.CookieContainer; - return (WebRequest) webRequest; - } - - public string GetString(string url) - { - this._IsJson = false; - return this.DownloadString(url); - } - - public string GetJson(string url) - { - this._IsJson = true; - return this.DownloadString(url); - } - } -} diff --git a/Clients/TransmissionClient.cs b/Clients/TransmissionClient.cs deleted file mode 100644 index ac0cf89..0000000 --- a/Clients/TransmissionClient.cs +++ /dev/null @@ -1,227 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.TransmissionClient -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using Newtonsoft.Json; -using NLog; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; - -namespace TLO.local -{ - internal class TransmissionClient : ITorrentClient - { - private static Logger _logger; - private TLOWebClient _webClient; - private string _URL; - private string svcCredentials; - - public TransmissionClient(string serverName, int port, string userName, string userPass) - { - if (TransmissionClient._logger == null) - TransmissionClient._logger = LogManager.GetLogger("TransmissionClient"); - this._webClient = new TLOWebClient(Encoding.UTF8, "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0", "application/json, text/javascript, */*; q=0.01", true); - this._webClient.Encoding = Encoding.UTF8; - this.svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + userPass)); - this._webClient.Headers.Add("Authorization", "Basic " + this.svcCredentials); - this._URL = string.Format("http://{0}:{1}/transmission/rpc", (object) serverName, (object) port); - try - { - this.Ping(); - } - catch - { - TransmissionClient._logger.Debug(string.Format("Имя сервера: {0}; Порт сервера: {1}", (object) serverName, (object) port)); - throw; - } - } - - public List GetAllTorrentHash() - { - try - { - TransmissionClient.Querty querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes("{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"totalSize\", \"percentDone\", \"error\", \"status\"]}}")))); - if (querty == null || querty.arguments == null || (querty.arguments.torrents == null || querty.arguments.torrents.Length == 0)) - return new List(); - return ((IEnumerable) querty.arguments.torrents).Select((Func) (t => new TopicInfo() - { - Hash = t.hashString.ToUpper(), - IsKeep = t.percentDone == Decimal.One && t.error == 0, - IsDownload = true, - IsRun = !(t.percentDone == Decimal.One) || t.error != 0 ? new bool?() : new bool?(t.status == 6) - })).ToList(); - } - catch (Exception ex) - { - TransmissionClient._logger.Error(ex.Message); - TransmissionClient._logger.Debug(ex.StackTrace); - throw ex; - } - } - - public IEnumerable GetFiles(TopicInfo topic) - { - yield break; - } - - public void DistributionStop(IEnumerable data) - { - TransmissionClient.Querty querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes("{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); - if (querty == null || querty.arguments == null || (querty.arguments.torrents == null || querty.arguments.torrents.Length == 0)) - return; - int[] array = ((IEnumerable) querty.arguments.torrents).Join(data, (Func) (t => t.hashString.ToUpper()), (Func) (d => d), (Func) ((t, d) => t.id)).ToArray(); - if (array.Length == 0) - return; - this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object) new - { - method = "torrent-stop", - arguments = new{ ids = array } - }))); - } - - public void DistributionPause(IEnumerable data) - { - TransmissionClient.Querty querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes("{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); - if (querty == null || querty.arguments == null || (querty.arguments.torrents == null || querty.arguments.torrents.Length == 0)) - return; - int[] array = ((IEnumerable) querty.arguments.torrents).Join(data, (Func) (t => t.hashString.ToUpper()), (Func) (d => d), (Func) ((t, d) => t.id)).ToArray(); - if (array.Length == 0) - return; - this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object) new - { - method = "torrent-stop", - arguments = new{ ids = array } - }))); - } - - public void DistributionStart(IEnumerable data) - { - TransmissionClient.Querty querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes("{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); - if (querty == null || querty.arguments == null || (querty.arguments.torrents == null || querty.arguments.torrents.Length == 0)) - return; - int[] array = ((IEnumerable) querty.arguments.torrents).Join(data, (Func) (t => t.hashString.ToUpper()), (Func) (d => d), (Func) ((t, d) => t.id)).ToArray(); - if (array.Length == 0) - return; - this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object) new - { - method = "torrent-start", - arguments = new{ ids = array } - }))); - } - - public bool Ping() - { - while (true) - { - try - { - this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes("{\"method\":\"session-get\"}")); - return true; - } - catch (WebException ex) - { - this._webClient.Headers.Add("X-Transmission-Session-Id", ex.Response.Headers["X-Transmission-Session-Id"]); - } - catch (Exception ex) - { - TransmissionClient._logger.Error(ex.Message); - TransmissionClient._logger.Debug(ex.StackTrace); - throw ex; - } - } - } - - public bool SetDefaultFolder(string dir) - { - return true; - } - - public bool SetDefaultLabel(string label) - { - return true; - } - - public string GetDefaultFolder() - { - return string.Empty; - } - - public void SendTorrentFile(string path, string file) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (FileStream fileStream = System.IO.File.OpenRead(file)) - { - fileStream.CopyTo((Stream) memoryStream); - this.SendTorrentFile(path, Path.GetFileName(file), memoryStream.ToArray()); - } - } - } - - public void SendTorrentFile(string path, string filename, byte[] fdata) - { - string base64String = Convert.ToBase64String(fdata); - this._webClient.UploadData(this._URL, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object) new - { - method = "torrent-add", - arguments = new - { - paused = false, - downloadDir = path, - metainfo = base64String - } - }).Replace("downloadDir", "download-dir"))); - } - - public string[] GetTrackers(string hash) - { - return (string[]) null; - } - - public bool SetTrackers(string hash, string[] trackers) - { - return true; - } - - public bool SetLabel(string hash, string label) - { - return true; - } - - public bool SetLabel(IEnumerable hash, string label) - { - return true; - } - - private class Querty - { - public TransmissionClient.Argument arguments { get; set; } - } - - private class Argument - { - public TransmissionClient.Torrent[] torrents { get; set; } - } - - private class Torrent - { - public int id { get; set; } - - public string hashString { get; set; } - - public long totalSize { get; set; } - - public Decimal percentDone { get; set; } - - public int error { get; set; } - - public int status { get; set; } - } - } -} diff --git a/Clients/uTorrentClient.cs b/Clients/uTorrentClient.cs deleted file mode 100644 index eed1dd6..0000000 --- a/Clients/uTorrentClient.cs +++ /dev/null @@ -1,395 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.uTorrentClient -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using NLog; -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; -using System.Web; - -namespace TLO.local -{ - internal class uTorrentClient : ITorrentClient - { - private static Logger _logger; - private TLOWebClient _webClient; - private string _ServerName; - private int _ServerPort; - private string svcCredentials; - private string token; - - public uTorrentClient(string serverName, int port, string userName, string userPass) - { - if (uTorrentClient._logger == null) - uTorrentClient._logger = LogManager.GetLogger("uTorrentClient"); - this._webClient = new TLOWebClient(); - this._webClient.Encoding = Encoding.UTF8; - this.svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + userPass)); - this._webClient.Headers.Add("Authorization", "Basic " + this.svcCredentials); - this._ServerName = serverName; - this._ServerPort = port; - try - { - this.Ping(); - } - catch - { - uTorrentClient._logger.Debug(string.Format("Имя сервера: {0}; Порт сервера: {1}", (object) this._ServerName, (object) this._ServerPort)); - throw; - } - } - - public bool Ping() - { - try - { - string[] array = ((IEnumerable) this._webClient.GetString(string.Format("http://{0}:{1}/gui/", (object) this._ServerName, (object) this._ServerPort)).Split(new string[1] - { - "div" - }, StringSplitOptions.RemoveEmptyEntries)).Where((Func) (x => x.Contains("token"))).ToArray(); - if (array.Length != 0) - this.token = array[0].Split(new char[2] - { - '>', - '<' - }, StringSplitOptions.RemoveEmptyEntries)[1]; - else - this.token = (string) null; - return true; - } - catch - { - throw; - } - } - - public List GetAllTorrentHash() - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "list", "1" }); - object[][] objArray = JsonConvert.DeserializeObject(this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))))["torrents"].ToObject(); - if (objArray == null) - return new List(); - return ((IEnumerable) objArray).Select(x => new - { - Hash = (x[0] as string).ToUpper(), - Name = x[2] as string, - Size = x[3].GetType() == typeof (int) ? (long) (int) x[3] : (x[3].GetType() == typeof (long) ? (long) x[3] : 0L), - Status = this.IntToArrayBool((long) x[1]), - PercentComplite = (Decimal) ((long) x[4]) * new Decimal(1, 0, 0, false, (byte) 1) - }).Select(x => new TopicInfo() - { - Hash = x.Hash, - TorrentName = x.Name, - Size = x.Size, - IsKeep = x.Status != null && x.PercentComplite == new Decimal(100) && (x.Status[3] && !x.Status[4]) && x.Status[7], - IsDownload = true, - IsPause = x.Status[5], - IsRun = !(x.PercentComplite == new Decimal(100)) || !x.Status[3] || (x.Status[4] || !x.Status[7]) ? new bool?() : new bool?(x.Status[0]) - }).ToList(); - } - - public IEnumerable GetFiles(TopicInfo topic) - { - if (topic != null && !string.IsNullOrEmpty(topic.Hash)) - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "getfiles" }); - source.Add(new string[2]{ "hash", topic.Hash }); - JToken jtoken1 = JsonConvert.DeserializeObject(this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))))["files"]; - if (jtoken1 != null) - { - foreach (JToken jtoken2 in (IEnumerable) jtoken1.ToObject()[1].ToObject()) - yield return jtoken2.ToObject()[0].ToString(); - } - } - } - - private bool[] IntToArrayBool(long value) - { - BitArray bitArray = new BitArray(new int[1] - { - (int) value - }); - bool[] flagArray = new bool[bitArray.Count]; - bitArray.CopyTo((Array) flagArray, 0); - return flagArray; - } - - public void DistributionStop(IEnumerable data) - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "stop" }); - source.AddRange(data.Select((Func) (x => new string[2] - { - "hash", - x - }))); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - } - - public void DistributionPause(IEnumerable data) - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "pause" }); - source.AddRange(data.Select((Func) (x => new string[2] - { - "hash", - x - }))); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - } - - public void DistributionStart(IEnumerable data) - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "start" }); - source.AddRange(data.Select((Func) (x => new string[2] - { - "hash", - x - }))); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - } - - public bool SetDefaultFolder(string dir) - { - try - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "setsetting" }); - source.Add(new string[2] - { - "s", - "dir_active_download" - }); - source.Add(new string[2] - { - "v", - HttpUtility.UrlEncode(dir) - }); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - Thread.Sleep(100); - return this.GetDefaultFolder() == dir; - } - catch - { - return false; - } - } - - public string GetDefaultFolder() - { - try - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "getsettings" }); - object[][] objArray1 = JsonConvert.DeserializeObject(this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))))["settings"].ToObject(); - if (objArray1 == null) - return string.Empty; - object[] objArray2 = ((IEnumerable) objArray1).Where((Func) (x => x[0] as string == "dir_active_download")).FirstOrDefault(); - if (objArray2 == null) - return string.Empty; - return objArray2[2] as string; - } - catch - { - return (string) null; - } - } - - public bool SetDefaultLabel(string label) - { - try - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "setsetting" }); - source.Add(new string[2]{ "s", "dir_add_label" }); - source.Add(new string[2] - { - "v", - HttpUtility.UrlEncode(label) - }); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - Thread.Sleep(200); - return this.GetDefaultLabel() == label; - } - catch - { - return false; - } - } - - public string GetDefaultLabel() - { - try - { - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "getsettings" }); - object[][] objArray1 = JsonConvert.DeserializeObject(this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))))["settings"].ToObject(); - if (objArray1 == null) - return string.Empty; - object[] objArray2 = ((IEnumerable) objArray1).Where((Func) (x => x[0] as string == "dir_add_label")).FirstOrDefault(); - if (objArray2 == null) - return string.Empty; - return objArray2[2] as string; - } - catch - { - return (string) null; - } - } - - public void SendTorrentFile(string path, string file) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (FileStream fileStream = System.IO.File.OpenRead(file)) - { - fileStream.CopyTo((Stream) memoryStream); - this.SendTorrentFile(path, Path.GetFileName(file), memoryStream.ToArray()); - } - } - } - - public void SendTorrentFile(string path, string filename, byte[] fdata) - { - string str = "----WebKitFormBoundary1vZaMilolI9TchBt"; - using (MemoryStream memoryStream = new MemoryStream()) - { - byte[] bytes1 = Encoding.ASCII.GetBytes(string.Format("--{0}\r\nContent-Disposition: form-data; name=\"torrent_file\"; filename=\"{1}\"\r\nContent-Type: application/x-bittorrent\r\n\r\n", (object) str, (object) filename)); - memoryStream.Write(bytes1, 0, bytes1.Length); - memoryStream.Write(fdata, 0, fdata.Length); - byte[] bytes2 = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}--\r\n", (object) str)); - memoryStream.Write(bytes2, 0, bytes2.Length); - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "add-file" }); - HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - httpWebRequest.Method = "POST"; - httpWebRequest.KeepAlive = true; - httpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; - httpWebRequest.ContentType = "multipart/form-data; boundary=" + str; - httpWebRequest.Headers.Add("Authorization", this._webClient.Headers.Get("Authorization")); - httpWebRequest.Headers.Add("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"); - byte[] array = memoryStream.ToArray(); - httpWebRequest.ContentLength = (long) array.Length; - using (Stream requestStream = httpWebRequest.GetRequestStream()) - requestStream.Write(array, 0, array.Length); - } - } - - public string[] GetTrackers(string hash) - { - return (string[]) null; - } - - public bool SetTrackers(string hash, string[] trackers) - { - try - { - string str = string.Join("\r\n\r\n", trackers) + "\r\n"; - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "setprops", "setprops" }); - source.Add(new string[2]{ "hash", hash }); - source.Add(new string[2]{ "s", "trackers" }); - source.Add(new string[2] - { - "v", - HttpUtility.UrlEncode(str) - }); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - Thread.Sleep(100); - string[] trackers1 = this.GetTrackers(hash); - if (trackers1 == null) - return false; - return string.Join("\r\n\r\n", trackers1) + "\r\n" == str; - } - catch - { - return false; - } - } - - public bool SetLabel(string hash, string label) - { - Thread.Sleep(100); - List source = new List(); - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "setprops" }); - source.Add(new string[2]{ "hash", hash }); - source.Add(new string[2]{ "s", "label" }); - source.Add(new string[2]{ "v", label }); - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - Thread.Sleep(100); - return true; - } - - public bool SetLabel(IEnumerable hashs, string label) - { - if (hashs == null || hashs.Count() == 0) - return true; - List source = new List(); - foreach (string str in hashs) - { - if (source.Count() == 0) - { - if (!string.IsNullOrWhiteSpace(this.token)) - source.Add(new string[2]{ "token", this.token }); - source.Add(new string[2]{ "action", "setprops" }); - } - source.Add(new string[2]{ "s", "label" }); - source.Add(new string[2]{ "hash", str }); - source.Add(new string[2]{ "v", label }); - if (source.Count() > 150) - { - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - source.Clear(); - } - Thread.Sleep(100); - } - if (source.Count() != 0) - this._webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", (object) this._ServerName, (object) this._ServerPort, (object) string.Join("&", source.Select((Func) (x => string.Join("=", x)))))); - return true; - } - - private class tt - { - public int build { get; set; } - - public List files { get; set; } - } - } -} diff --git a/Forms/FolderNameDialog.cs b/Forms/FolderNameDialog.cs deleted file mode 100644 index f69256f..0000000 --- a/Forms/FolderNameDialog.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Forms.FolderNameDialog -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; -using System.ComponentModel; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Windows.Forms; - -namespace TLO.local.Forms -{ - public class FolderNameDialog : Form - { - private IContainer components; - private Button btCancel; - private Button btOk; - private Button btAbort; - private TextBox txtFolderName; - - public string SelectedPath - { - get - { - return this.txtFolderName.Text; - } - set - { - this.txtFolderName.Text = string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim(); - } - } - - public FolderNameDialog() - { - this.InitializeComponent(); - } - - private void ClickButton(object sender, EventArgs e) - { - if (sender == this.btAbort) - { - this.DialogResult = DialogResult.Abort; - this.Close(); - } - else if (sender == this.btCancel) - { - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - else - { - if (sender != this.btOk) - return; - foreach (char invalidFileNameChar in Path.GetInvalidFileNameChars()) - { - if (this.SelectedPath.Contains(invalidFileNameChar)) - { - int num = (int) MessageBox.Show("Название каталога содержит недопустимый символ: " + invalidFileNameChar.ToString()); - return; - } - } - this.DialogResult = DialogResult.OK; - this.Close(); - } - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - this.btCancel = new Button(); - this.btOk = new Button(); - this.btAbort = new Button(); - this.txtFolderName = new TextBox(); - this.SuspendLayout(); - this.btCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - this.btCancel.Location = new Point(426, 38); - this.btCancel.Name = "btCancel"; - this.btCancel.Size = new Size(75, 23); - this.btCancel.TabIndex = 0; - this.btCancel.Text = "Пропустить"; - this.btCancel.UseVisualStyleBackColor = true; - this.btCancel.Click += new EventHandler(this.ClickButton); - this.btOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - this.btOk.Location = new Point(345, 38); - this.btOk.Name = "btOk"; - this.btOk.Size = new Size(75, 23); - this.btOk.TabIndex = 1; - this.btOk.Text = "Применить"; - this.btOk.UseVisualStyleBackColor = true; - this.btOk.Click += new EventHandler(this.ClickButton); - this.btAbort.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - this.btAbort.Location = new Point(12, 38); - this.btAbort.Name = "btAbort"; - this.btAbort.Size = new Size(75, 23); - this.btAbort.TabIndex = 2; - this.btAbort.Text = "Прервать"; - this.btAbort.UseVisualStyleBackColor = true; - this.btAbort.Click += new EventHandler(this.ClickButton); - this.txtFolderName.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - this.txtFolderName.Location = new Point(12, 12); - this.txtFolderName.Name = "txtFolderName"; - this.txtFolderName.Size = new Size(489, 20); - this.txtFolderName.TabIndex = 3; - this.AutoScaleDimensions = new SizeF(6f, 13f); - this.AutoScaleMode = AutoScaleMode.Font; - this.ClientSize = new Size(513, 73); - this.ControlBox = false; - this.Controls.Add((Control) this.txtFolderName); - this.Controls.Add((Control) this.btAbort); - this.Controls.Add((Control) this.btOk); - this.Controls.Add((Control) this.btCancel); - this.FormBorderStyle = FormBorderStyle.FixedToolWindow; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "FolderNameDialog"; - this.StartPosition = FormStartPosition.CenterScreen; - this.Text = "Запрос наименования каталога"; - this.ResumeLayout(false); - this.PerformLayout(); - } - } -} diff --git a/Forms/ForumPages.Designer.cs b/Forms/ForumPages.Designer.cs deleted file mode 100644 index 565670f..0000000 --- a/Forms/ForumPages.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Этот код создан программой. -// Исполняемая версия:4.0.30319.42000 -// -// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае -// повторной генерации кода. -// -//------------------------------------------------------------------------------ - -namespace TLO.local.Forms { - using System; - - - /// - /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - /// - // Этот класс создан автоматически классом StronglyTypedResourceBuilder - // с помощью такого средства, как ResGen или Visual Studio. - // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen - // с параметром /str или перестройте свой проект VS. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ForumPages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ForumPages() { - } - - /// - /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TLO.local.Forms.ForumPages", typeof(ForumPages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Перезаписывает свойство CurrentUICulture текущего потока для всех - /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/Forms/ForumPages.cs b/Forms/ForumPages.cs deleted file mode 100644 index fae1fd4..0000000 --- a/Forms/ForumPages.cs +++ /dev/null @@ -1,121 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.ForumPages -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace TLO.local -{ - public class ForumPages : UserControl - { - private IContainer components; - private Panel panel1; - - private List> Urls { get; set; } - - public ForumPages() - { - this.Urls = new List>(); - this.InitializeComponent(); - } - - public void LoadSettings() - { - this.panel1.Controls.Clear(); - Dictionary, Tuple> reports = ClientLocalDB.Current.GetReports(new int?()); - List categoriesEnable = ClientLocalDB.Current.GetCategoriesEnable(); - categoriesEnable.Add(new Category() - { - CategoryID = 0, - Name = " Сводный отчет", - FullName = " Сводный отчет" - }); - int num1 = 0; - int y = 10; - foreach (Category category1 in (IEnumerable) categoriesEnable.OrderBy((Func) (x => x.FullName))) - { - Category category = category1; - Label label = new Label(); - label.AutoSize = true; - label.Location = new Point(3, y); - label.Size = new Size(35, 13); - label.TabIndex = num1; - label.Text = category.FullName; - this.panel1.Controls.Add((Control) label); - y += 16; - KeyValuePair, Tuple>[] array = reports.Where, Tuple>>((Func, Tuple>, bool>) (x => x.Key.Item1 == category.CategoryID)).OrderBy, Tuple>, int>((Func, Tuple>, int>) (x => x.Key.Item2)).ToArray, Tuple>>(); - KeyValuePair, Tuple>[] keyValuePairArray; - if (array.Length != 0) - keyValuePairArray = array; - else - keyValuePairArray = new KeyValuePair, Tuple>[1] - { - new KeyValuePair, Tuple>(new Tuple(category.CategoryID, 0), new Tuple("", "")) - }; - foreach (KeyValuePair, Tuple> keyValuePair in keyValuePairArray) - { - if (category.CategoryID != 0 || keyValuePair.Key.Item2 == 0) - { - int num2 = num1 + 1; - TextBox textBox1 = new TextBox(); - textBox1.Enabled = false; - textBox1.Location = new Point(6, y); - textBox1.Size = new Size(123, 20); - textBox1.TabIndex = num2; - textBox1.Text = "Отчет " + (keyValuePair.Key.Item2 != 0 ? keyValuePair.Key.Item2.ToString() + (keyValuePair.Value.Item2 == "Резерв" ? " (Резерв)" : "") : " (Шапка)"); - if (category.CategoryID == 0) - textBox1.Text = "Сводный отчет"; - this.panel1.Controls.Add((Control) textBox1); - num1 = num2 + 1; - TextBox textBox2 = new TextBox(); - textBox2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - textBox2.Location = new Point(135, y); - textBox2.Size = new Size(this.panel1.Size.Width - 135, 20); - textBox2.TabIndex = num1; - textBox2.Text = string.IsNullOrWhiteSpace(keyValuePair.Value.Item1) ? "" : keyValuePair.Value.Item1; - this.panel1.Controls.Add((Control) textBox2); - this.Urls.Add(new Tuple(keyValuePair.Key.Item1, keyValuePair.Key.Item2, textBox2)); - y += 26; - } - } - } - } - - public void Save() - { - ClientLocalDB.Current.SaveSettingsReport(this.Urls.Select, Tuple>((Func, Tuple>) (x => new Tuple(x.Item1, x.Item2, x.Item3.Text))).ToList>()); - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - this.panel1 = new Panel(); - this.SuspendLayout(); - this.panel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - this.panel1.AutoScroll = true; - this.panel1.Location = new Point(0, 0); - this.panel1.Name = "panel1"; - this.panel1.Size = new Size(606, 440); - this.panel1.TabIndex = 0; - this.AutoScaleDimensions = new SizeF(6f, 13f); - this.AutoScaleMode = AutoScaleMode.Font; - this.Controls.Add((Control) this.panel1); - this.Name = "ForumPages"; - this.Size = new Size(606, 440); - this.ResumeLayout(false); - } - } -} diff --git a/Forms/GetLableName.cs b/Forms/GetLableName.cs deleted file mode 100644 index 3e1c53e..0000000 --- a/Forms/GetLableName.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Forms.GetLableName -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; -using System.ComponentModel; -using System.Drawing; -using System.Windows.Forms; - -namespace TLO.local.Forms -{ - public class GetLableName : Form - { - private IContainer components; - private TextBox _txtLabel; - private Label label1; - private Button btOk; - private Button btCancel; - - internal string Value - { - get - { - return this._txtLabel.Text; - } - set - { - this._txtLabel.Text = value; - } - } - - public GetLableName() - { - this.InitializeComponent(); - } - - private void btClick(object sender, EventArgs e) - { - if (sender == this.btCancel) - { - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - else - { - if (sender != this.btOk) - return; - this.DialogResult = DialogResult.OK; - } - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - this._txtLabel = new TextBox(); - this.label1 = new Label(); - this.btOk = new Button(); - this.btCancel = new Button(); - this.SuspendLayout(); - this._txtLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - this._txtLabel.Location = new Point(94, 12); - this._txtLabel.Name = "_txtLabel"; - this._txtLabel.Size = new Size(408, 20); - this._txtLabel.TabIndex = 0; - this.label1.AutoSize = true; - this.label1.Location = new Point(12, 15); - this.label1.Name = "label1"; - this.label1.Size = new Size(76, 13); - this.label1.TabIndex = 1; - this.label1.Text = "Новая метка:"; - this.btOk.Anchor = AnchorStyles.Top | AnchorStyles.Right; - this.btOk.Location = new Point(427, 38); - this.btOk.Name = "btOk"; - this.btOk.Size = new Size(75, 23); - this.btOk.TabIndex = 2; - this.btOk.Text = "Применить"; - this.btOk.UseVisualStyleBackColor = true; - this.btOk.Click += new EventHandler(this.btClick); - this.btCancel.Anchor = AnchorStyles.Top | AnchorStyles.Right; - this.btCancel.Location = new Point(346, 38); - this.btCancel.Name = "btCancel"; - this.btCancel.Size = new Size(75, 23); - this.btCancel.TabIndex = 3; - this.btCancel.Text = "Отмена"; - this.btCancel.UseVisualStyleBackColor = true; - this.btCancel.Click += new EventHandler(this.btClick); - this.AutoScaleDimensions = new SizeF(6f, 13f); - this.AutoScaleMode = AutoScaleMode.Font; - this.ClientSize = new Size(514, 72); - this.Controls.Add((Control) this.btCancel); - this.Controls.Add((Control) this.btOk); - this.Controls.Add((Control) this.label1); - this.Controls.Add((Control) this._txtLabel); - this.FormBorderStyle = FormBorderStyle.None; - this.Name = "GetLableName"; - this.StartPosition = FormStartPosition.CenterScreen; - this.Text = "GetLableName"; - this.ResumeLayout(false); - this.PerformLayout(); - } - } -} diff --git a/Forms/MainForm.Designer.cs b/Forms/MainForm.Designer.cs deleted file mode 100644 index ae42e0c..0000000 --- a/Forms/MainForm.Designer.cs +++ /dev/null @@ -1,93 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Этот код создан программой. -// Исполняемая версия:4.0.30319.42000 -// -// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае -// повторной генерации кода. -// -//------------------------------------------------------------------------------ - -namespace TLO.local.Forms { - using System; - - - /// - /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - /// - // Этот класс создан автоматически классом StronglyTypedResourceBuilder - // с помощью такого средства, как ResGen или Visual Studio. - // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen - // с параметром /str или перестройте свой проект VS. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class MainForm { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal MainForm() { - } - - /// - /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TLO.local.Forms.MainForm", typeof(MainForm).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Перезаписывает свойство CurrentUICulture текущего потока для всех - /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Поиск локализованного ресурса типа System.Boolean, аналогичного False. - /// - internal static bool _dgvReportDownloads_GenerateMember { - get { - object obj = ResourceManager.GetObject("_dgvReportDownloads.GenerateMember", resourceCulture); - return ((bool)(obj)); - } - } - - /// - /// Поиск локализованного ресурса типа System.Drawing.Point, аналогичного {X=17,Y=17}. - /// - internal static System.Drawing.Point menuStrip1_TrayLocation { - get { - object obj = ResourceManager.GetObject("menuStrip1.TrayLocation", resourceCulture); - return ((System.Drawing.Point)(obj)); - } - } - - /// - /// Поиск локализованного ресурса типа System.Drawing.Point, аналогичного {X=132,Y=17}. - /// - internal static System.Drawing.Point statusStrip1_TrayLocation { - get { - object obj = ResourceManager.GetObject("statusStrip1.TrayLocation", resourceCulture); - return ((System.Drawing.Point)(obj)); - } - } - } -} diff --git a/Forms/MainForm.cs b/Forms/MainForm.cs deleted file mode 100644 index b190e7d..0000000 --- a/Forms/MainForm.cs +++ /dev/null @@ -1,1871 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.MainForm -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Windows.Forms; -using TLO.local.Forms; - -namespace TLO.local -{ - public class MainForm : Form - { - private Logger _logger = LogManager.GetCurrentClassLogger(); - private DateTime _LastRunTimer = DateTime.Now; - private BindingSource _CategorySource = new BindingSource(); - private BindingSource _TopicsSource = new BindingSource(); - - private Dictionary> backgroundWorkers = - new Dictionary>(); - - private string headText; - private Timer tmr; - private NotifyIcon notifyIcon; - private IContainer components; - private MenuStrip menuStrip1; - private ToolStripMenuItem файлToolStripMenuItem; - private ToolStripMenuItem menuSettingsToolStripMenuItem; - private ToolStripMenuItem ExitToolStripMenuItem; - private ToolStripMenuItem отчетыToolStripMenuItem; - private ComboBox _cbCategory; - private Label label1; - private TabControl tabControl1; - private TabPage _tpReportDownloads; - private CheckBox _cbBlackList; - private Label label2; - private ComboBox _cbCategoryFilters; - private Label label3; - private LinkLabel _llSelectedTopicsToTorrentClient; - private LinkLabel _llDownloadSelectTopics; - private LinkLabel _llSelectedTopicsToBlackList; - private LinkLabel _llSelectedTopicsDeleteFromBlackList; - private LinkLabel linkSetNewLabel; - private LinkLabel linkLabel5; - private Label label4; - private LinkLabel _llUpdateTopicsByCategory; - private LinkLabel _llUpdateCountSeedersByCategory; - private LinkLabel _llUpdateDataDromTorrentClient; - private ToolStripMenuItem задачиToolStripMenuItem; - private ToolStripMenuItem UpdateCountSeedersToolStripMenuItem; - private ToolStripMenuItem UpdateListTopicsToolStripMenuItem; - private ToolStripMenuItem UpdateKeepTopicsToolStripMenuItem; - private ToolStripMenuItem ClearDatabaseToolStripMenuItem; - private Label _lbTotal; - private ToolStripMenuItem SendReportsToForumToolStripMenuItem; - private ToolStripMenuItem CreateReportsToolStripMenuItem; - private StatusStrip statusStrip1; - private ToolStripStatusLabel toolStripStatusLabel1; - private ToolStripProgressBar toolStripProgressBar1; - private ToolStripMenuItem RuningStopingDistributionToolStripMenuItem; - private ToolStripSeparator toolStripSeparator1; - private ToolStripSeparator toolStripSeparator2; - private NumericUpDown _cbCountSeeders; - private TabPage tabReports; - private ToolStripMenuItem DevlToolStripMenuItem; - private ToolStripMenuItem ClearKeeperListsToolStripMenuItem; - private TabPage tabPage1; - private TabPage tabConsolidatedReport; - private TextBox _txtConsolidatedReport; - private TabPage ConsolidatedTorrentClientsReport; - private TextBox _tbConsolidatedTorrentClientsReport; - private ToolStripMenuItem CreateConsolidatedReportByTorrentClientsToolStripMenuItem; - private DateTimePicker _DateRegistration; - private Label label5; - private TabControl _tcCetegoriesRootReports; - private TabPage tabPage2; - private TabPage tabPage3; - private ToolStripMenuItem LoadListKeepersToolStripMenuItem; - private ToolStripMenuItem _btSaveToFile; - private ToolStripMenuItem _btLoadSettingsFromFile; - private ToolStripSeparator toolStripSeparator4; - private DataGridViewTextBoxColumn ColumnReport1DgvTopicID; - private DataGridViewCheckBoxColumn ColumnReport1DgvSelect; - private DataGridViewTextBoxColumn ColumnReport1DgvStatus; - private DataGridViewTextBoxColumn ColumnReport1DgvSize; - private DataGridViewLinkColumn ColumnReport1DgvName; - private DataGridViewLinkColumn ColumnReport1DgvAlternative; - private DataGridViewTextBoxColumn ColumnReport1DgvSeeders; - private DataGridViewTextBoxColumn ColumnReport1DgvAvgSeeders; - private DataGridViewTextBoxColumn ColumnReport1DgvRegTime; - private DataGridViewTextBoxColumn ColumnReport1DgvKeeperCount; - private DataGridViewCheckBoxColumn ColumnReport1DgvBlack; - private ToolStripSeparator toolStripSeparator3; - private DataGridView _dataGridTopicsList; - - private bool IsClose { get; set; } - - public MainForm() - { - this.InitializeComponent(); - this._DateRegistration.Value = DateTime.Now.AddDays(-30.0); - this.Text = this.headText = string.Format("TLO {0}", - (object) FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion); - this._cbCountSeeders.Value = new Decimal(5); - this._cbCategoryFilters.SelectedItem = (object) "Не скачан торрент"; - this._CategorySource.Clear(); - this._CategorySource.DataSource = (object) ClientLocalDB.Current.GetCategoriesEnable(); - this._CategorySource.CurrentChanged += new EventHandler(this.SelectionChanged); - this._cbCategory.DataSource = (object) this._CategorySource; - if (this._CategorySource.Count > 0) - this._CategorySource.Position = 1; - this._TopicsSource.CurrentChanged += new EventHandler(this.SelectionChanged); - this._dataGridTopicsList.AutoGenerateColumns = false; - this._dataGridTopicsList.ClearSelection(); - this._dataGridTopicsList.DataSource = (object) this._TopicsSource; - this.Disposed += new EventHandler(this.MainForm_Disposed); - this.Resize += new EventHandler(this.MainForm_Resize); - this.tmr = new Timer(); - this.tmr.Tick += new EventHandler(this.tmr_Tick); - this.tmr.Interval = 1000; - this.tmr.Start(); - this.IsClose = false; - this.notifyIcon = new NotifyIcon(); - this.notifyIcon.Icon = (Icon) new ComponentResourceManager(typeof(MainForm)).GetObject("$this.Icon"); - this.notifyIcon.MouseDoubleClick += new MouseEventHandler(this.notifyIcon_MouseDoubleClick); - this.notifyIcon.Visible = true; - this.WriteReports(); - } - - private void MenuClick(object sender, EventArgs e) - { - try - { - if (sender == this.menuSettingsToolStripMenuItem) - { - if (new SettingsForm().ShowDialog() == DialogResult.OK) - { - this._CategorySource.Clear(); - this._CategorySource.DataSource = (object) null; - this._CategorySource.DataSource = (object) ClientLocalDB.Current.GetCategoriesEnable(); - this._CategorySource.Position = 0; - if (MessageBox.Show( - "Запустить загрузку/обновление информации о топиках (раздачах) по всем категориям?", - "Обновление данных", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, - MessageBoxDefaultButton.Button1) == DialogResult.OK) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateTopicsByCategories), - "Полное обновление информации о топиках (раздачах) по всем категориям...", - (object) ClientLocalDB.Current.GetCategoriesEnable()); - } - } - else if (sender == this.UpdateCountSeedersToolStripMenuItem) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateCountSeedersByAllCategories), - "Обновление кол-ва сидов на раздачах...", sender); - else if (sender == this.UpdateListTopicsToolStripMenuItem) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateTopicsByCategories), - "Полное обновление информации о топиках (раздачах) по всем категориям...", - (object) ClientLocalDB.Current.GetCategoriesEnable()); - else if (sender == this.UpdateKeepTopicsToolStripMenuItem) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateHashFromAllTorrentClients), - "Полное обновление информации из Torrent-клиентов...", (object) null); - else if (sender == this.ClearDatabaseToolStripMenuItem) - { - if (MessageBox.Show( - "Вы пытаетесь очистить базу данны от текущих данных (статистику и информацию о топиках).\r\n Продолжить?", - "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, - MessageBoxDefaultButton.Button2) != DialogResult.Yes) - return; - ClientLocalDB.Current.ClearDatabase(); - } - else if (sender == this.ClearKeeperListsToolStripMenuItem) - { - if (MessageBox.Show("Вы пытаетесь очистить базу данны от данных других хранителей.\r\n Продолжить?", - "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, - MessageBoxDefaultButton.Button2) != DialogResult.Yes) - return; - ClientLocalDB.Current.ClearKeepers(); - this.SelectionChanged((object) this._CategorySource, (EventArgs) null); - } - else if (sender == this.SendReportsToForumToolStripMenuItem) - { - if (MessageBox.Show( - "Отправка отчетов на форум может продолжаться продолжительное время.\r\n Продолжить?", - "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, - MessageBoxDefaultButton.Button2) != DialogResult.Yes) - return; - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwSendReports), "Отправка отчетов на форум...", - (object) this); - } - else if (sender == this.CreateReportsToolStripMenuItem) - { - if (MessageBox.Show( - "Сборка отчетов может продолжаться продолжительное время и потребуется обновить список раздач и информацию из торрент-клиентов.\r\n Продолжит?", - "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, - MessageBoxDefaultButton.Button2) != DialogResult.Yes) - return; - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateCountSeedersByAllCategories), - "Обновление кол-ва сидов на раздачах...", sender); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateHashFromAllTorrentClients), - "Обновление информации из Torrent-клиентов...", sender); - } - else if (sender == this.RuningStopingDistributionToolStripMenuItem) - { - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateCountSeedersByAllCategories), - "Обновление кол-ва сидов на раздачах...", sender); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwRuningAndStopingDistributions), - "Обновление информации из Torrent-клиентов...", sender); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwCreateReportsTorrentClients), - "Построение сводного отчета по торрент-клиентам...", sender); - } - else if (sender == this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwCreateReportsTorrentClients), - "Построение сводного отчета по торрент-клиентам...", sender); - else if (sender == this.LoadListKeepersToolStripMenuItem) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateKeepersByAllCategories), - "Обновление данных о хранителях...", sender); - else if (sender == this.ExitToolStripMenuItem) - { - this.IsClose = true; - this.Close(); - } - else if (sender == this.DevlToolStripMenuItem) - { - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateKeepersByAllCategories), - "Обновление данных о хранителях...", sender); - try - { - RuTrackerOrg ruTrackerOrg = - new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass); - } - catch (Exception ex) - { - int num = (int) MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); - } - } - else if (sender == this._btSaveToFile) - this.SaveSetingsToFile(); - else if (sender == this._btLoadSettingsFromFile) - this.ReadSettingsFromFile(); - } - catch (Exception ex) - { - Cursor.Current = Cursors.Default; - int num = (int) MessageBox.Show(ex.Message); - } - - Cursor.Current = Cursors.Default; - } - - private void tmr_Tick(object sender, EventArgs e) - { - if (this.backgroundWorkers.Count > 0) - { - this.Text = string.Format("{0} ({1})", (object) this.headText, (object) "Выполняются задачи..."); - this.notifyIcon.Text = - string.Format("{0} ({1})", (object) this.headText, (object) "Выполняются задачи..."); - } - else - { - DateTime lastRunTimer = this._LastRunTimer; - DateTime now = DateTime.Now; - DateTime dateTime1 = now.AddMinutes((double) -Settings.Current.PeriodRunAndStopTorrents); - TimeSpan timeSpan = lastRunTimer - dateTime1; - if (timeSpan.TotalSeconds > 0.0) - { - this.Text = string.Format("{0} ({1:hh\\:mm\\:ss})", (object) this.headText, (object) timeSpan); - this.notifyIcon.Text = - string.Format("{0} ({1:hh\\:mm\\:ss})", (object) this.headText, (object) timeSpan); - } - else - { - try - { - DateTime lastUpdateTopics = Settings.Current.LastUpdateTopics; - now = DateTime.Now; - DateTime dateTime2 = now.AddDays(-1.0); - if (lastUpdateTopics < dateTime2) - { - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateTopicsByCategories), - "Полное обновление информации о топиках (раздачах) по всем категориям...", - (object) ClientLocalDB.Current.GetCategoriesEnable()); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateKeepersByAllCategories), - "Обновление данных о хранителях...", sender); - Settings current = Settings.Current; - now = DateTime.Now; - DateTime date = now.Date; - current.LastUpdateTopics = date; - Settings.Current.Save(); - } - else - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateCountSeedersByAllCategories), - "Обновление информации о кол-ве сидов на раздачах...", sender); - - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwRuningAndStopingDistributions), - "Запуск/Остановка раздач в Torrent-клиентах...", sender); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwCreateReportsTorrentClients), - "Построение сводного отчета по торрент-клиентам...", sender); - } - catch (Exception ex) - { - this._logger.Error(ex.Message); - this._logger.Debug(ex.Message, ex); - } - - this._LastRunTimer = DateTime.Now; - } - } - } - - private void MainForm_Disposed(object sender, EventArgs e) - { - this.tmr.Stop(); - this.tmr.Dispose(); - } - - private void MainForm_Resize(object sender, EventArgs e) - { - if (this.WindowState != FormWindowState.Minimized) - return; - this.Hide(); - } - - private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) - { - this.Show(); - this.WindowState = FormWindowState.Normal; - } - - private void SelectionChanged(object sender, EventArgs e) - { - if (sender == this._CategorySource || sender == this._cbCountSeeders || - (sender == this._cbBlackList || sender == this._cbCategoryFilters) || sender == this._DateRegistration) - { - this._TopicsSource.Clear(); - if (this._CategorySource.Current != null) - { - Category current = this._CategorySource.Current as Category; - int num = (int) this._cbCountSeeders.Value; - DateTime regTime = this._DateRegistration.Value; - bool? isKeep = new bool?(); - bool? isKeepers = new bool?(); - bool? isDownload = new bool?(); - bool? isBlack = new bool?(); - bool? isPoster = new bool?(); - string selectedItem = this._cbCategoryFilters.SelectedItem as string; - if (!string.IsNullOrWhiteSpace(selectedItem)) - { - switch (selectedItem) - { - case "Есть хранитель": - isKeepers = new bool?(true); - break; - case "Не скачан торрент": - isDownload = new bool?(false); - break; - case "Не скачан торрент и есть хранитель": - isDownload = new bool?(false); - isKeepers = new bool?(true); - break; - case "Не скачан торрент и нет хранителя": - isDownload = new bool?(false); - isKeepers = new bool?(false); - break; - case "Не скачано": - isDownload = new bool?(false); - break; - case "Не храню": - isKeep = new bool?(false); - break; - case "Скачиваю раздачу": - isDownload = new bool?(true); - isKeep = new bool?(false); - break; - case "Храню": - isKeep = new bool?(true); - break; - case "Храню и есть хранитель": - isKeep = new bool?(true); - isKeepers = new bool?(true); - break; - case "Я релизер": - isPoster = new bool?(false); - break; - } - } - - isBlack = new bool?(this._cbBlackList.Checked); - List topicInfoList = new List(); - List source = !Settings.Current.IsAvgCountSeeders - ? ClientLocalDB.Current.GetTopics(regTime, current.CategoryID, - num > -1 ? new int?(num) : new int?(), new int?(), isKeep, isKeepers, isDownload, isBlack, - isPoster) - : ClientLocalDB.Current.GetTopics(regTime, current.CategoryID, new int?(), - num > -1 ? new int?(num) : new int?(), isKeep, isKeepers, isDownload, isBlack, isPoster); - this._lbTotal.Text = string.Format("Кол-во: {0}; Размер: {1}", (object) source.Count(), - (object) TopicInfo.sizeToString(source.Sum((Func) (x => x.Size)))); - this._TopicsSource.DataSource = (object) source; - } - } - - if (sender != this._CategorySource || this._CategorySource.Current == null) - return; - this.tabReports.Controls.Clear(); - Dictionary, Tuple> reports = - ClientLocalDB.Current.GetReports(new int?((this._CategorySource.Current as Category).CategoryID)); - if (reports.Count, Tuple>>() > 0) - { - Size size = this.tabReports.Size; - TabControl tabControl = new TabControl(); - tabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - tabControl.Location = new Point(0, 0); - tabControl.SelectedIndex = 0; - tabControl.Size = new Size(size.Width, size.Height); - this.tabReports.Controls.Add((Control) tabControl); - foreach (KeyValuePair, Tuple> keyValuePair in ( - IEnumerable, Tuple>>) reports - .OrderBy, Tuple>, int>( - (Func, Tuple>, int>) (x => x.Key.Item2))) - { - if (!(keyValuePair.Value.Item2 == "Резерв") && !(keyValuePair.Value.Item2 == "Удалено")) - { - TabPage tabPage = new TabPage(); - TextBox textBox = new TextBox(); - tabPage.Location = new Point(4, 22); - tabPage.Padding = new Padding(3); - tabPage.Text = string.Format("Сидируемое: отчет № {0}", (object) keyValuePair.Key.Item2); - if (keyValuePair.Key.Item2 == 0) - tabPage.Text = string.Format("Шапка сидируемого"); - tabPage.UseVisualStyleBackColor = true; - tabPage.AutoScroll = true; - textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | - AnchorStyles.Right; - textBox.Location = new Point(0, 0); - textBox.Multiline = true; - textBox.ReadOnly = true; - textBox.ScrollBars = ScrollBars.Both; - textBox.Size = new Size(size.Width - 8, size.Height - 20); - textBox.Text = keyValuePair.Value.Item2; - tabControl.Controls.Add((Control) tabPage); - tabPage.Controls.Add((Control) textBox); - } - } - } - else - { - Size size = this.tabReports.Size; - TabControl tabControl = new TabControl(); - tabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - tabControl.Location = new Point(0, 0); - tabControl.SelectedIndex = 0; - tabControl.Size = new Size(size.Width, size.Height); - this.tabReports.Controls.Add((Control) tabControl); - TabPage tabPage = new TabPage(); - TextBox textBox = new TextBox(); - tabControl.Controls.Add((Control) tabPage); - tabPage.Controls.Add((Control) textBox); - tabPage.Location = new Point(4, 22); - tabPage.Padding = new Padding(3); - tabPage.Text = string.Format("Для информации"); - tabPage.UseVisualStyleBackColor = true; - textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - textBox.Location = new Point(0, 0); - textBox.Multiline = true; - textBox.ReadOnly = true; - textBox.ScrollBars = ScrollBars.Both; - textBox.Size = new Size(size.Width - 8, size.Height - 20); - textBox.Text = - "Здесь должен быть отчет о сидируемом, но его нет.\r\nВозможные причины: сервис не успел обработать задачи сервера на скачивание страниц, прочитать torrent-файлы или не смог подключиться к torrent-клиенту\r\n\r\nЕсли на вкладке \"Не скачано\" есть раздачи которые Вы храните, то попробуйте сформировать отчет принудительно из пункта меню"; - } - } - - private void LinkClick(object sender, EventArgs e) - { - if (this.backgroundWorkers.Count != 0 && - MessageBox.Show("Выполняются другие задачи. Добавить в очередь новое?", "Внимание", - MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != - DialogResult.Yes) - return; - Cursor.Current = Cursors.WaitCursor; - try - { - Category current = this._CategorySource.Current as Category; - if (current == null) - return; - if (sender == this._llUpdateCountSeedersByCategory) - Logic.UpdateSeedersByCategory(current); - else if (sender == this._llUpdateTopicsByCategory) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateTopicsByCategory), - "Обновление списков по разделу...", (object) current); - else if (sender == this._llUpdateDataDromTorrentClient) - Logic.LoadHashFromClients(current.TorrentClientUID); - else if (sender == this._llDownloadSelectTopics) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwDownloadTorrentFiles), - "Скачиваются выделеные торрент-файлы в каталог...", - (object) new Tuple, MainForm>( - (this._TopicsSource.DataSource as List) - .Where((Func) (x => x.Checked)).ToList(), this)); - else if (sender == this._llSelectedTopicsToTorrentClient) - { - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwSendTorrentFileToTorrentClient), - "Скачиваются и добавляются в торрент-клиент выделенные раздачи...", - (object) new Tuple, Category>(this, - (this._TopicsSource.DataSource as List) - .Where((Func) (x => x.Checked)).ToList(), current)); - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwUpdateHashFromTorrentClientsByCategoryUID), - "Обновляем список раздач из торрент-клиента...", (object) current); - } - else if (sender == this._llSelectedTopicsToBlackList) - { - List list = (this._TopicsSource.DataSource as List) - .Where((Func) (x => x.Checked)).ToList(); - list.ForEach((Action) (x => x.IsBlackList = true)); - ClientLocalDB.Current.SaveTopicInfo(list, false); - } - else if (sender == this._llSelectedTopicsDeleteFromBlackList) - { - List list = (this._TopicsSource.DataSource as List) - .Where((Func) (x => x.Checked)).ToList(); - list.ForEach((Action) (x => x.IsBlackList = false)); - ClientLocalDB.Current.SaveTopicInfo(list, false); - } - else if (sender == this.linkSetNewLabel) - { - if (current == null) - return; - GetLableName getLableName = new GetLableName(); - getLableName.Value = string.IsNullOrWhiteSpace(current.Label) ? current.FullName : current.Label; - if (getLableName.ShowDialog() == DialogResult.OK) - this.dwCreateAndRun(new DoWorkEventHandler(Logic.bwSetLabels), - "Установка пользовательских меток...", - (object) new Tuple, string>(this, - (this._TopicsSource.DataSource as List) - .Where((Func) (x => x.Checked)).ToList(), - getLableName.Value)); - } - - this.SelectionChanged((object) this._CategorySource, (EventArgs) null); - } - catch (Exception ex) - { - this._logger.Error(ex); - int num = (int) MessageBox.Show("Произошла ошибка:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - - Cursor.Current = Cursors.Default; - } - - private void ContentClick(object sender, DataGridViewCellEventArgs e) - { - if (this._dataGridTopicsList.Columns[e.ColumnIndex].DataPropertyName == "Name") - { - try - { - int? nullable = this._dataGridTopicsList.Rows[e.RowIndex].Cells[0].Value as int?; - if (!nullable.HasValue) - return; - Process.Start(string.Format("https://{1}/forum/viewtopic.php?t={0}", (object) nullable.Value, - Settings.Current.HostRuTrackerOrg)); - } - catch - { - } - } - else - { - if (!(this._dataGridTopicsList.Columns[e.ColumnIndex].DataPropertyName == "Alternative")) - return; - try - { - int? topicId = this._dataGridTopicsList.Rows[e.RowIndex].Cells[0].Value as int?; - if (!topicId.HasValue) - return; - List dataSource = this._TopicsSource.DataSource as List; - if (dataSource == null) - return; - TopicInfo topicInfo = dataSource - .Where((Func) (x => x.TopicID == topicId.Value)) - .FirstOrDefault(); - if (topicInfo == null) - return; - string empty1 = string.Empty; - string empty2 = string.Empty; - int num1 = topicInfo.Name.IndexOf('/'); - string str1; - if (topicInfo.Name.IndexOf(']') > num1 && num1 != -1) - str1 = ((IEnumerable) topicInfo.Name.Split('/')).FirstOrDefault(); - else if (topicInfo.Name.IndexOf(']') < num1 && num1 != -1) - str1 = ((IEnumerable) topicInfo.Name.Split('/')).FirstOrDefault().Split(']')[1]; - else if (num1 == -1 && topicInfo.Name.IndexOf('[') < 5 && topicInfo.Name.IndexOf('[') != -1) - str1 = ((IEnumerable) topicInfo.Name.Split(']')[1].Split('[')).FirstOrDefault(); - else if (num1 == -1 && topicInfo.Name.IndexOf('[') != -1) - str1 = ((IEnumerable) topicInfo.Name.Split('[')).FirstOrDefault(); - else - str1 = ((IEnumerable) topicInfo.Name.Split('[')).FirstOrDefault(); - int num2 = topicInfo.Name.IndexOf('[', num1 > -1 ? num1 : 0); - if (num2 < 5) - { - int startIndex = topicInfo.Name.IndexOf(']') + 1; - num2 = topicInfo.Name.IndexOf('[', startIndex); - } - - string str2 = topicInfo.Name.Substring(num2 == -1 ? 0 : num2 + 1); - if (!string.IsNullOrWhiteSpace(str2)) - str2 = ((IEnumerable) str2.Split(new char[3] - { - ',', - ' ', - ']' - }, StringSplitOptions.RemoveEmptyEntries)).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str2)) - str1 = str1 + " " + str2; - Process.Start(string.Format("https://{2}/forum/tracker.php?f={0}&nm={1}", - (object) topicInfo.CategoryID, (object) str1, Settings.Current.HostRuTrackerOrg)); - } - catch - { - } - } - } - - private void dwCreateAndRun(DoWorkEventHandler e, string comment = "...", object argument = null) - { - BackgroundWorker key = new BackgroundWorker(); - key.WorkerReportsProgress = true; - key.WorkerSupportsCancellation = true; - key.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - key.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); - key.DoWork += e; - this.backgroundWorkers.Add(key, new Tuple(DateTime.Now, argument, comment)); - if (this.backgroundWorkers.Count != 1) - return; - key.RunWorkerAsync(argument); - } - - private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - this.toolStripProgressBar1.Value = 0; - this.toolStripProgressBar1.Visible = false; - this.toolStripStatusLabel1.Text = ""; - this.toolStripStatusLabel1.Visible = false; - this.statusStrip1.Refresh(); - if (sender != null && sender is BackgroundWorker && - this.backgroundWorkers.ContainsKey(sender as BackgroundWorker)) - { - BackgroundWorker key = sender as BackgroundWorker; - if (this.backgroundWorkers.ContainsKey(key)) - this.backgroundWorkers.Remove(key); - key.Dispose(); - } - - if (e.Result != null) - this._logger.Info(e.Result); - if (this.backgroundWorkers.Count > 0) - { - // запуск следующей задачи. - KeyValuePair> keyValuePair = this.backgroundWorkers - .OrderBy>, DateTime>( - (Func>, DateTime>) (x => - x.Value.Item1)).First>>(); - keyValuePair.Key.RunWorkerAsync(keyValuePair.Value.Item2); - } - else - { - // записываем окончательные изменения в БД после выполнения последней задачи. - this.SelectionChanged((object) this._CategorySource, (EventArgs) null); - this.WriteReports(); - ClientLocalDB.Current.SaveToDatabase(); - } - - GC.Collect(); - } - - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) - { - if (sender != null && sender is BackgroundWorker && - this.backgroundWorkers.ContainsKey(sender as BackgroundWorker)) - { - this.toolStripStatusLabel1.Text = this.backgroundWorkers[sender as BackgroundWorker].Item3; - this.toolStripProgressBar1.Visible = true; - this.toolStripStatusLabel1.Visible = true; - this.statusStrip1.Refresh(); - } - - this.toolStripProgressBar1.Value = - e.ProgressPercentage < 0 || e.ProgressPercentage > 100 ? 100 : e.ProgressPercentage; - } - - protected override void OnClosing(CancelEventArgs e) - { - if (!this.IsClose) - { - e.Cancel = true; - this.WindowState = FormWindowState.Minimized; - } - else - this.notifyIcon.Visible = false; - } - - private void _dgvReportDownloads_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - DataGridViewColumn column = this._dataGridTopicsList.Columns[e.ColumnIndex]; - if (column == this.ColumnReport1DgvSelect) - { - List dataSource = this._TopicsSource.DataSource as List; - if (dataSource == null) - return; - List list = dataSource.ToList(); - list.ForEach((Action) (x => - { - TopicInfo topicInfo = x; - topicInfo.Checked = !topicInfo.Checked; - })); - this._TopicsSource.Clear(); - this._TopicsSource.DataSource = (object) list; - } - else - { - DataGridViewColumn sortedColumn = this._dataGridTopicsList.SortedColumn; - SortOrder sortOrder = - column.HeaderCell.SortGlyphDirection == SortOrder.None || - column.HeaderCell.SortGlyphDirection == SortOrder.Descending - ? SortOrder.Ascending - : SortOrder.Descending; - if (column == null) - { - int num = (int) MessageBox.Show("Select a single column and try again.", "Error: Invalid Selection", - MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - else - { - List dataSource = this._TopicsSource.DataSource as List; - if (dataSource == null) - return; - List list1 = dataSource.ToList(); - List list2; - if (column == this.ColumnReport1DgvSize) - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1.OrderBy( - (Func) (d => d.Size)) - : (IEnumerable) list1.OrderByDescending( - (Func) (d => d.Size))).ToList(); - else if (column == this.ColumnReport1DgvName) - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1.OrderBy( - (Func) (d => d.Name)) - : (IEnumerable) list1.OrderByDescending( - (Func) (d => d.Name))).ToList(); - else if (column == this.ColumnReport1DgvSeeders) - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1 - .OrderBy((Func) (d => d.Seeders)) - .ThenBy((Func) (d => this.Name)) - : (IEnumerable) list1 - .OrderByDescending((Func) (d => d.Seeders)) - .ThenBy((Func) (d => this.Name))) - .ToList(); - else if (column == this.ColumnReport1DgvAvgSeeders) - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1 - .OrderBy((Func) (d => d.AvgSeeders)) - .ThenBy((Func) (d => this.Name)) - : (IEnumerable) list1 - .OrderByDescending( - (Func) (d => d.AvgSeeders)) - .ThenBy((Func) (d => this.Name))) - .ToList(); - else if (column == this.ColumnReport1DgvRegTime) - { - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1 - .OrderBy((Func) (d => d.RegTime)) - .ThenBy((Func) (d => this.Name)) - : (IEnumerable) list1 - .OrderByDescending( - (Func) (d => d.RegTime)) - .ThenBy((Func) (d => this.Name))) - .ToList(); - } - else if (column == this.ColumnReport1DgvKeeperCount) - { - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1 - .OrderBy((Func) (d => d.KeeperCount)) - .ThenBy((Func) (d => this.Name)) - : (IEnumerable) list1 - .OrderByDescending((Func) (d => d.KeeperCount)) - .ThenBy((Func) (d => this.Name))) - .ToList(); - } - else - { - if (column != this.ColumnReport1DgvStatus) - return; - list2 = (sortOrder == SortOrder.Ascending - ? (IEnumerable) list1 - .OrderBy((Func) (d => d.StatusToString)) - .ThenBy((Func) (d => this.Name)) - : (IEnumerable) list1 - .OrderByDescending( - (Func) (d => d.StatusToString)) - .ThenBy((Func) (d => this.Name))) - .ToList(); - } - - this._TopicsSource.Clear(); - this._TopicsSource.DataSource = (object) list2; - column.HeaderCell.SortGlyphDirection = sortOrder; - } - } - } - - private void _dgvReportDownloads_Click(object sender, EventArgs e) - { - if (this._dataGridTopicsList.Columns.GetColumnCount(DataGridViewElementStates.Selected) == 1) - { - DataGridViewColumn selectedColumn = this._dataGridTopicsList.SelectedColumns[0]; - } - - Console.WriteLine(""); - } - - private void WriteReports() - { - ClientLocalDB.Current.CreateReportByRootCategories(); - this._tcCetegoriesRootReports.Controls.Clear(); - Dictionary, Tuple> reports = ClientLocalDB.Current.GetReports(new int?(0)); - string str1 = reports - .Where, Tuple>>( - (Func, Tuple>, bool>) (x => x.Key.Item2 == 0)) - .Select, Tuple>, string>( - (Func, Tuple>, string>) (x => x.Value.Item2)) - .FirstOrDefault(); - this._txtConsolidatedReport.Text = string.IsNullOrWhiteSpace(str1) ? string.Empty : str1; - string str2 = reports - .Where, Tuple>>( - (Func, Tuple>, bool>) (x => x.Key.Item2 == 1)) - .Select, Tuple>, string>( - (Func, Tuple>, string>) (x => x.Value.Item2)) - .FirstOrDefault(); - this._tbConsolidatedTorrentClientsReport.Text = string.IsNullOrWhiteSpace(str2) ? string.Empty : str2; - IEnumerable categories = ClientLocalDB.Current.GetCategories() - .Where((Func) (x => x.CategoryID > 100000)); - Size size = this._tcCetegoriesRootReports.Size; - foreach (Category category in categories) - { - string str3 = ClientLocalDB.Current.GetReports(new int?(category.CategoryID)) - .Where, Tuple>>( - (Func, Tuple>, bool>) (x => x.Key.Item2 == 0)) - .Select, Tuple>, string>( - (Func, Tuple>, string>) (x => x.Value.Item2)) - .FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(str3)) - { - TabPage tabPage = new TabPage(); - TextBox textBox = new TextBox(); - tabPage.Location = new Point(4, 22); - tabPage.Padding = new Padding(3); - tabPage.Text = category.Name; - tabPage.UseVisualStyleBackColor = true; - tabPage.AutoScroll = true; - tabPage.Size = size; - textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - textBox.Location = new Point(0, 0); - textBox.Multiline = true; - textBox.ReadOnly = true; - textBox.ScrollBars = ScrollBars.Both; - textBox.Size = new Size(size.Width - 8, size.Height - 20); - textBox.Text = str3; - this._tcCetegoriesRootReports.Controls.Add((Control) tabPage); - tabPage.Controls.Add((Control) textBox); - } - } - } - - private void SaveSetingsToFile() - { - try - { - string empty = string.Empty; - SaveFileDialog saveFileDialog = new SaveFileDialog(); - saveFileDialog.DefaultExt = "tloback"; - saveFileDialog.Filter = "Файл архивных настроек|*.tloback"; - if (saveFileDialog.ShowDialog() != DialogResult.OK) - return; - string fileName = saveFileDialog.FileName; - if (string.IsNullOrWhiteSpace(fileName)) - return; - using (FileStream fileStream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write)) - { - using (BinaryWriter binaryWriter = new BinaryWriter((Stream) fileStream, Encoding.UTF8)) - { - foreach (TorrentClientInfo torrentClient in ClientLocalDB.Current.GetTorrentClients()) - { - binaryWriter.Write("TorrentClientInfo"); - binaryWriter.Write(torrentClient.UID.ToString()); - binaryWriter.Write(torrentClient.Name); - binaryWriter.Write(torrentClient.Type); - binaryWriter.Write(torrentClient.ServerName); - binaryWriter.Write(torrentClient.ServerPort); - binaryWriter.Write(torrentClient.UserName); - binaryWriter.Write(torrentClient.UserPassword); - } - - foreach (Category category in ClientLocalDB.Current.GetCategoriesEnable()) - { - binaryWriter.Write("Category"); - binaryWriter.Write(category.CategoryID); - binaryWriter.Write(category.CountSeeders); - binaryWriter.Write(category.TorrentClientUID.ToString()); - binaryWriter.Write(category.Folder); - binaryWriter.Write(category.CreateSubFolder); - binaryWriter.Write(category.IsSaveTorrentFiles); - binaryWriter.Write(category.IsSaveWebPage); - binaryWriter.Write(category.Label); - } - - int[] cats = ClientLocalDB.Current.GetCategoriesEnable() - .Select((Func) (x => x.CategoryID)).ToArray(); - Dictionary, Tuple> reports = - ClientLocalDB.Current.GetReports(new int?()); - foreach (KeyValuePair, Tuple> keyValuePair in reports - .Where, Tuple>>( - (Func, Tuple>, bool>) (x => - ((IEnumerable) cats).Contains(x.Key.Item1)))) - { - binaryWriter.Write("Report"); - binaryWriter.Write(keyValuePair.Key.Item1); - binaryWriter.Write(keyValuePair.Key.Item2); - binaryWriter.Write(keyValuePair.Value.Item1); - } - } - } - } - catch (Exception ex) - { - this._logger.Error(ex.Message); - this._logger.Trace(ex.StackTrace); - } - } - - private void ReadSettingsFromFile() - { - try - { - string empty = string.Empty; - OpenFileDialog openFileDialog = new OpenFileDialog(); - openFileDialog.DefaultExt = "tloback"; - openFileDialog.Filter = "Файл архивных настроек|*.tloback"; - if (openFileDialog.ShowDialog() != DialogResult.OK) - return; - string fileName = openFileDialog.FileName; - if (string.IsNullOrWhiteSpace(fileName)) - return; - List torrentClientInfoList = new List(); - List categoryList = new List(); - List> result = new List>(); - using (FileStream fileStream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Read)) - { - using (BinaryReader binaryReader = new BinaryReader((Stream) fileStream)) - { - while (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position) - { - string str = binaryReader.ReadString(); - if (!(str == "TorrentClientInfo")) - { - if (!(str == "Category")) - { - if (str == "Report") - result.Add(new Tuple(binaryReader.ReadInt32(), - binaryReader.ReadInt32(), binaryReader.ReadString())); - } - else - { - Category category = new Category() - { - CategoryID = binaryReader.ReadInt32(), - IsEnable = true, - CountSeeders = binaryReader.ReadInt32(), - TorrentClientUID = Guid.Parse(binaryReader.ReadString()), - Folder = binaryReader.ReadString(), - CreateSubFolder = binaryReader.ReadInt32(), - IsSaveTorrentFiles = binaryReader.ReadBoolean(), - IsSaveWebPage = binaryReader.ReadBoolean(), - Label = binaryReader.ReadString() - }; - categoryList.Add(category); - } - } - else - { - TorrentClientInfo torrentClientInfo = new TorrentClientInfo() - { - UID = Guid.Parse(binaryReader.ReadString()), - Name = binaryReader.ReadString(), - Type = binaryReader.ReadString(), - ServerName = binaryReader.ReadString(), - ServerPort = binaryReader.ReadInt32(), - UserName = binaryReader.ReadString(), - UserPassword = binaryReader.ReadString() - }; - torrentClientInfoList.Add(torrentClientInfo); - } - } - - ClientLocalDB.Current.SaveTorrentClients((IEnumerable) torrentClientInfoList, - false); - ClientLocalDB.Current.CategoriesSave((IEnumerable) categoryList, false); - ClientLocalDB.Current.SaveSettingsReport(result); - ClientLocalDB.Current.SaveToDatabase(); - } - } - } - catch (Exception ex) - { - this._logger.Error(ex.Message); - this._logger.Trace(ex.StackTrace); - } - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.файлToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.menuSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this._btSaveToFile = new System.Windows.Forms.ToolStripMenuItem(); - this._btLoadSettingsFromFile = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.ExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.отчетыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.SendReportsToForumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.CreateReportsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.задачиToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.RuningStopingDistributionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.UpdateCountSeedersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.UpdateListTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.UpdateKeepTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.LoadListKeepersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.ClearKeeperListsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ClearDatabaseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.DevlToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this._cbCategory = new System.Windows.Forms.ComboBox(); - this.label1 = new System.Windows.Forms.Label(); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this._tpReportDownloads = new System.Windows.Forms.TabPage(); - this._DateRegistration = new System.Windows.Forms.DateTimePicker(); - this.label5 = new System.Windows.Forms.Label(); - this._cbCountSeeders = new System.Windows.Forms.NumericUpDown(); - this._lbTotal = new System.Windows.Forms.Label(); - this._llUpdateTopicsByCategory = new System.Windows.Forms.LinkLabel(); - this._llUpdateCountSeedersByCategory = new System.Windows.Forms.LinkLabel(); - this._llUpdateDataDromTorrentClient = new System.Windows.Forms.LinkLabel(); - this.label4 = new System.Windows.Forms.Label(); - this.linkLabel5 = new System.Windows.Forms.LinkLabel(); - this.linkSetNewLabel = new System.Windows.Forms.LinkLabel(); - this._llSelectedTopicsDeleteFromBlackList = new System.Windows.Forms.LinkLabel(); - this._llSelectedTopicsToTorrentClient = new System.Windows.Forms.LinkLabel(); - this._llDownloadSelectTopics = new System.Windows.Forms.LinkLabel(); - this._llSelectedTopicsToBlackList = new System.Windows.Forms.LinkLabel(); - this._cbBlackList = new System.Windows.Forms.CheckBox(); - this.label2 = new System.Windows.Forms.Label(); - this._cbCategoryFilters = new System.Windows.Forms.ComboBox(); - this.label3 = new System.Windows.Forms.Label(); - this.ColumnReport1DgvTopicID = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvSelect = new System.Windows.Forms.DataGridViewCheckBoxColumn(); - this.ColumnReport1DgvStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvName = new System.Windows.Forms.DataGridViewLinkColumn(); - this.ColumnReport1DgvAlternative = new System.Windows.Forms.DataGridViewLinkColumn(); - this.ColumnReport1DgvSeeders = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvAvgSeeders = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvRegTime = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvKeeperCount = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnReport1DgvBlack = new System.Windows.Forms.DataGridViewCheckBoxColumn(); - this.tabReports = new System.Windows.Forms.TabPage(); - this.tabConsolidatedReport = new System.Windows.Forms.TabPage(); - this._txtConsolidatedReport = new System.Windows.Forms.TextBox(); - this.ConsolidatedTorrentClientsReport = new System.Windows.Forms.TabPage(); - this._tbConsolidatedTorrentClientsReport = new System.Windows.Forms.TextBox(); - this.tabPage1 = new System.Windows.Forms.TabPage(); - this._tcCetegoriesRootReports = new System.Windows.Forms.TabControl(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.tabPage3 = new System.Windows.Forms.TabPage(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); - _dataGridTopicsList = new System.Windows.Forms.DataGridView(); - this.menuStrip1.SuspendLayout(); - this.tabControl1.SuspendLayout(); - this._tpReportDownloads.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this._cbCountSeeders)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(_dataGridTopicsList)).BeginInit(); - this.tabConsolidatedReport.SuspendLayout(); - this.ConsolidatedTorrentClientsReport.SuspendLayout(); - this.tabPage1.SuspendLayout(); - this._tcCetegoriesRootReports.SuspendLayout(); - this.statusStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.файлToolStripMenuItem, - this.отчетыToolStripMenuItem, - this.задачиToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(1040, 24); - this.menuStrip1.TabIndex = 0; - this.menuStrip1.Text = "menuStrip1"; - // - // файлToolStripMenuItem - // - this.файлToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menuSettingsToolStripMenuItem, - this.toolStripSeparator4, - this._btSaveToFile, - this._btLoadSettingsFromFile, - this.toolStripSeparator3, - this.ExitToolStripMenuItem}); - this.файлToolStripMenuItem.Name = "файлToolStripMenuItem"; - this.файлToolStripMenuItem.Size = new System.Drawing.Size(48, 20); - this.файлToolStripMenuItem.Text = "Файл"; - // - // menuSettingsToolStripMenuItem - // - this.menuSettingsToolStripMenuItem.Name = "menuSettingsToolStripMenuItem"; - this.menuSettingsToolStripMenuItem.Size = new System.Drawing.Size(242, 22); - this.menuSettingsToolStripMenuItem.Text = "Настройки"; - this.menuSettingsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(239, 6); - // - // _btSaveToFile - // - this._btSaveToFile.Name = "_btSaveToFile"; - this._btSaveToFile.Size = new System.Drawing.Size(242, 22); - this._btSaveToFile.Text = "Сохранить настройки в файл"; - this._btSaveToFile.Click += new System.EventHandler(this.MenuClick); - // - // _btLoadSettingsFromFile - // - this._btLoadSettingsFromFile.Name = "_btLoadSettingsFromFile"; - this._btLoadSettingsFromFile.Size = new System.Drawing.Size(242, 22); - this._btLoadSettingsFromFile.Text = "Загрузить настройки из файла"; - this._btLoadSettingsFromFile.Click += new System.EventHandler(this.MenuClick); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(239, 6); - // - // ExitToolStripMenuItem - // - this.ExitToolStripMenuItem.Name = "ExitToolStripMenuItem"; - this.ExitToolStripMenuItem.Size = new System.Drawing.Size(242, 22); - this.ExitToolStripMenuItem.Text = "Выход"; - this.ExitToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // отчетыToolStripMenuItem - // - this.отчетыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.SendReportsToForumToolStripMenuItem, - this.CreateReportsToolStripMenuItem}); - this.отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; - this.отчетыToolStripMenuItem.Size = new System.Drawing.Size(60, 20); - this.отчетыToolStripMenuItem.Text = "Отчеты"; - // - // SendReportsToForumToolStripMenuItem - // - this.SendReportsToForumToolStripMenuItem.Name = "SendReportsToForumToolStripMenuItem"; - this.SendReportsToForumToolStripMenuItem.Size = new System.Drawing.Size(231, 22); - this.SendReportsToForumToolStripMenuItem.Text = "Отправить отчеты на форум"; - this.SendReportsToForumToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // CreateReportsToolStripMenuItem - // - this.CreateReportsToolStripMenuItem.Name = "CreateReportsToolStripMenuItem"; - this.CreateReportsToolStripMenuItem.Size = new System.Drawing.Size(231, 22); - this.CreateReportsToolStripMenuItem.Text = "Сформировать отчеты"; - this.CreateReportsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // задачиToolStripMenuItem - // - this.задачиToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.RuningStopingDistributionToolStripMenuItem, - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem, - this.toolStripSeparator1, - this.UpdateCountSeedersToolStripMenuItem, - this.UpdateListTopicsToolStripMenuItem, - this.UpdateKeepTopicsToolStripMenuItem, - this.LoadListKeepersToolStripMenuItem, - this.toolStripSeparator2, - this.ClearKeeperListsToolStripMenuItem, - this.ClearDatabaseToolStripMenuItem, - this.DevlToolStripMenuItem}); - this.задачиToolStripMenuItem.Name = "задачиToolStripMenuItem"; - this.задачиToolStripMenuItem.Size = new System.Drawing.Size(58, 20); - this.задачиToolStripMenuItem.Text = "Задачи"; - // - // RuningStopingDistributionToolStripMenuItem - // - this.RuningStopingDistributionToolStripMenuItem.Name = "RuningStopingDistributionToolStripMenuItem"; - this.RuningStopingDistributionToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.RuningStopingDistributionToolStripMenuItem.Text = "Запуск/Остановка раздач в торрент-клиентах"; - this.RuningStopingDistributionToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // CreateConsolidatedReportByTorrentClientsToolStripMenuItem - // - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Name = "CreateConsolidatedReportByTorrentClientsToolStripMenuItem"; - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Text = "Построить сводный отчет по торрент-клиентам"; - this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(376, 6); - // - // UpdateCountSeedersToolStripMenuItem - // - this.UpdateCountSeedersToolStripMenuItem.Name = "UpdateCountSeedersToolStripMenuItem"; - this.UpdateCountSeedersToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.UpdateCountSeedersToolStripMenuItem.Text = "Обновить кол-во сидов по всем разделам"; - this.UpdateCountSeedersToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // UpdateListTopicsToolStripMenuItem - // - this.UpdateListTopicsToolStripMenuItem.Name = "UpdateListTopicsToolStripMenuItem"; - this.UpdateListTopicsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.UpdateListTopicsToolStripMenuItem.Text = "Обновить список топиков по всем разделам"; - this.UpdateListTopicsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // UpdateKeepTopicsToolStripMenuItem - // - this.UpdateKeepTopicsToolStripMenuItem.Name = "UpdateKeepTopicsToolStripMenuItem"; - this.UpdateKeepTopicsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.UpdateKeepTopicsToolStripMenuItem.Text = "Обновить списки хранимого по всем Torrent-клиентам"; - this.UpdateKeepTopicsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // LoadListKeepersToolStripMenuItem - // - this.LoadListKeepersToolStripMenuItem.Name = "LoadListKeepersToolStripMenuItem"; - this.LoadListKeepersToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.LoadListKeepersToolStripMenuItem.Text = "Обновить данные о других хранителях"; - this.LoadListKeepersToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(376, 6); - // - // ClearKeeperListsToolStripMenuItem - // - this.ClearKeeperListsToolStripMenuItem.Name = "ClearKeeperListsToolStripMenuItem"; - this.ClearKeeperListsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.ClearKeeperListsToolStripMenuItem.Text = "Очистить списки хранителей со свод. значениями"; - this.ClearKeeperListsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // ClearDatabaseToolStripMenuItem - // - this.ClearDatabaseToolStripMenuItem.Name = "ClearDatabaseToolStripMenuItem"; - this.ClearDatabaseToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.ClearDatabaseToolStripMenuItem.Text = "Очистить списки разделов (удалить топики)"; - this.ClearDatabaseToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // DevlToolStripMenuItem - // - this.DevlToolStripMenuItem.Name = "DevlToolStripMenuItem"; - this.DevlToolStripMenuItem.Size = new System.Drawing.Size(379, 22); - this.DevlToolStripMenuItem.Text = "Не трогать и не спрашивать"; - this.DevlToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); - // - // _cbCategory - // - this._cbCategory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._cbCategory.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this._cbCategory.FormattingEnabled = true; - this._cbCategory.Location = new System.Drawing.Point(117, 27); - this._cbCategory.Name = "_cbCategory"; - this._cbCategory.Size = new System.Drawing.Size(911, 21); - this._cbCategory.TabIndex = 1; - this._cbCategory.SelectionChangeCommitted += new System.EventHandler(this.SelectionChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 30); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(99, 13); - this.label1.TabIndex = 2; - this.label1.Text = "Выберите раздел:"; - // - // tabControl1 - // - this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tabControl1.Controls.Add(this._tpReportDownloads); - this.tabControl1.Controls.Add(this.tabReports); - this.tabControl1.Controls.Add(this.tabConsolidatedReport); - this.tabControl1.Controls.Add(this.ConsolidatedTorrentClientsReport); - this.tabControl1.Controls.Add(this.tabPage1); - this.tabControl1.Location = new System.Drawing.Point(0, 54); - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1040, 462); - this.tabControl1.TabIndex = 3; - this.tabControl1.VisibleChanged += new System.EventHandler(this.SelectionChanged); - // - // _tpReportDownloads - // - this._tpReportDownloads.Controls.Add(this._DateRegistration); - this._tpReportDownloads.Controls.Add(this.label5); - this._tpReportDownloads.Controls.Add(this._cbCountSeeders); - this._tpReportDownloads.Controls.Add(this._lbTotal); - this._tpReportDownloads.Controls.Add(this._llUpdateTopicsByCategory); - this._tpReportDownloads.Controls.Add(this._llUpdateCountSeedersByCategory); - this._tpReportDownloads.Controls.Add(this._llUpdateDataDromTorrentClient); - this._tpReportDownloads.Controls.Add(this.label4); - this._tpReportDownloads.Controls.Add(this.linkLabel5); - this._tpReportDownloads.Controls.Add(this.linkSetNewLabel); - this._tpReportDownloads.Controls.Add(this._llSelectedTopicsDeleteFromBlackList); - this._tpReportDownloads.Controls.Add(this._llSelectedTopicsToTorrentClient); - this._tpReportDownloads.Controls.Add(this._llDownloadSelectTopics); - this._tpReportDownloads.Controls.Add(this._llSelectedTopicsToBlackList); - this._tpReportDownloads.Controls.Add(this._cbBlackList); - this._tpReportDownloads.Controls.Add(this.label2); - this._tpReportDownloads.Controls.Add(this._cbCategoryFilters); - this._tpReportDownloads.Controls.Add(this.label3); - this._tpReportDownloads.Controls.Add(_dataGridTopicsList); - this._tpReportDownloads.Location = new System.Drawing.Point(4, 22); - this._tpReportDownloads.Name = "_tpReportDownloads"; - this._tpReportDownloads.Padding = new System.Windows.Forms.Padding(3); - this._tpReportDownloads.Size = new System.Drawing.Size(1032, 436); - this._tpReportDownloads.TabIndex = 2; - this._tpReportDownloads.Text = "Обработка раздела"; - this._tpReportDownloads.UseVisualStyleBackColor = true; - // - // _DateRegistration - // - this._DateRegistration.Format = System.Windows.Forms.DateTimePickerFormat.Short; - this._DateRegistration.Location = new System.Drawing.Point(65, 10); - this._DateRegistration.Name = "_DateRegistration"; - this._DateRegistration.Size = new System.Drawing.Size(93, 20); - this._DateRegistration.TabIndex = 32; - this._DateRegistration.ValueChanged += new System.EventHandler(this.SelectionChanged); - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(8, 12); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(51, 13); - this.label5.TabIndex = 31; - this.label5.Text = "Дата до:"; - // - // _cbCountSeeders - // - this._cbCountSeeders.Location = new System.Drawing.Point(247, 10); - this._cbCountSeeders.Minimum = new decimal(new int[] { - 1, - 0, - 0, - -2147483648}); - this._cbCountSeeders.Name = "_cbCountSeeders"; - this._cbCountSeeders.Size = new System.Drawing.Size(40, 20); - this._cbCountSeeders.TabIndex = 30; - this._cbCountSeeders.ValueChanged += new System.EventHandler(this.SelectionChanged); - // - // _lbTotal - // - this._lbTotal.AutoSize = true; - this._lbTotal.Location = new System.Drawing.Point(8, 32); - this._lbTotal.Name = "_lbTotal"; - this._lbTotal.Size = new System.Drawing.Size(40, 13); - this._lbTotal.TabIndex = 29; - this._lbTotal.Text = "Итого:"; - // - // _llUpdateTopicsByCategory - // - this._llUpdateTopicsByCategory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._llUpdateTopicsByCategory.AutoSize = true; - this._llUpdateTopicsByCategory.Location = new System.Drawing.Point(836, 399); - this._llUpdateTopicsByCategory.Name = "_llUpdateTopicsByCategory"; - this._llUpdateTopicsByCategory.Size = new System.Drawing.Size(154, 13); - this._llUpdateTopicsByCategory.TabIndex = 28; - this._llUpdateTopicsByCategory.TabStop = true; - this._llUpdateTopicsByCategory.Text = "Обновить список по разделу"; - this._llUpdateTopicsByCategory.Click += new System.EventHandler(this.LinkClick); - // - // _llUpdateCountSeedersByCategory - // - this._llUpdateCountSeedersByCategory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._llUpdateCountSeedersByCategory.AutoSize = true; - this._llUpdateCountSeedersByCategory.Location = new System.Drawing.Point(836, 382); - this._llUpdateCountSeedersByCategory.Name = "_llUpdateCountSeedersByCategory"; - this._llUpdateCountSeedersByCategory.Size = new System.Drawing.Size(184, 13); - this._llUpdateCountSeedersByCategory.TabIndex = 27; - this._llUpdateCountSeedersByCategory.TabStop = true; - this._llUpdateCountSeedersByCategory.Text = "Обновить кол-во сидов по разделу"; - this._llUpdateCountSeedersByCategory.Click += new System.EventHandler(this.LinkClick); - // - // _llUpdateDataDromTorrentClient - // - this._llUpdateDataDromTorrentClient.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._llUpdateDataDromTorrentClient.AutoSize = true; - this._llUpdateDataDromTorrentClient.Location = new System.Drawing.Point(836, 416); - this._llUpdateDataDromTorrentClient.Name = "_llUpdateDataDromTorrentClient"; - this._llUpdateDataDromTorrentClient.Size = new System.Drawing.Size(184, 13); - this._llUpdateDataDromTorrentClient.TabIndex = 26; - this._llUpdateDataDromTorrentClient.TabStop = true; - this._llUpdateDataDromTorrentClient.Text = "Обновить инф. из торрент-клиента"; - this._llUpdateDataDromTorrentClient.Click += new System.EventHandler(this.LinkClick); - // - // label4 - // - this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(836, 35); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(141, 13); - this.label4.TabIndex = 23; - this.label4.Text = "Действия с выделенными"; - // - // linkLabel5 - // - this.linkLabel5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.linkLabel5.AutoSize = true; - this.linkLabel5.Location = new System.Drawing.Point(836, 102); - this.linkLabel5.Name = "linkLabel5"; - this.linkLabel5.Size = new System.Drawing.Size(186, 13); - this.linkLabel5.TabIndex = 22; - this.linkLabel5.TabStop = true; - this.linkLabel5.Text = "Удалить из Torrent-клиента+файлы"; - this.linkLabel5.Visible = false; - // - // linkSetNewLabel - // - this.linkSetNewLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.linkSetNewLabel.AutoSize = true; - this.linkSetNewLabel.Location = new System.Drawing.Point(836, 85); - this.linkSetNewLabel.Name = "linkSetNewLabel"; - this.linkSetNewLabel.Size = new System.Drawing.Size(100, 13); - this.linkSetNewLabel.TabIndex = 21; - this.linkSetNewLabel.TabStop = true; - this.linkSetNewLabel.Text = "Установить метку"; - this.linkSetNewLabel.Click += new System.EventHandler(this.LinkClick); - // - // _llSelectedTopicsDeleteFromBlackList - // - this._llSelectedTopicsDeleteFromBlackList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this._llSelectedTopicsDeleteFromBlackList.AutoSize = true; - this._llSelectedTopicsDeleteFromBlackList.Location = new System.Drawing.Point(836, 136); - this._llSelectedTopicsDeleteFromBlackList.Name = "_llSelectedTopicsDeleteFromBlackList"; - this._llSelectedTopicsDeleteFromBlackList.Size = new System.Drawing.Size(147, 13); - this._llSelectedTopicsDeleteFromBlackList.TabIndex = 20; - this._llSelectedTopicsDeleteFromBlackList.TabStop = true; - this._llSelectedTopicsDeleteFromBlackList.Text = "Удалить из черного списка"; - this._llSelectedTopicsDeleteFromBlackList.Click += new System.EventHandler(this.LinkClick); - // - // _llSelectedTopicsToTorrentClient - // - this._llSelectedTopicsToTorrentClient.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this._llSelectedTopicsToTorrentClient.AutoSize = true; - this._llSelectedTopicsToTorrentClient.Location = new System.Drawing.Point(836, 68); - this._llSelectedTopicsToTorrentClient.Name = "_llSelectedTopicsToTorrentClient"; - this._llSelectedTopicsToTorrentClient.Size = new System.Drawing.Size(141, 13); - this._llSelectedTopicsToTorrentClient.TabIndex = 19; - this._llSelectedTopicsToTorrentClient.TabStop = true; - this._llSelectedTopicsToTorrentClient.Text = "Добавить в Torrent-клиент"; - this._llSelectedTopicsToTorrentClient.Click += new System.EventHandler(this.LinkClick); - // - // _llDownloadSelectTopics - // - this._llDownloadSelectTopics.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this._llDownloadSelectTopics.AutoSize = true; - this._llDownloadSelectTopics.Location = new System.Drawing.Point(836, 51); - this._llDownloadSelectTopics.Name = "_llDownloadSelectTopics"; - this._llDownloadSelectTopics.Size = new System.Drawing.Size(122, 13); - this._llDownloadSelectTopics.TabIndex = 18; - this._llDownloadSelectTopics.TabStop = true; - this._llDownloadSelectTopics.Text = "Скачать Torrent-файлы"; - this._llDownloadSelectTopics.Click += new System.EventHandler(this.LinkClick); - // - // _llSelectedTopicsToBlackList - // - this._llSelectedTopicsToBlackList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this._llSelectedTopicsToBlackList.AutoSize = true; - this._llSelectedTopicsToBlackList.Location = new System.Drawing.Point(836, 119); - this._llSelectedTopicsToBlackList.Name = "_llSelectedTopicsToBlackList"; - this._llSelectedTopicsToBlackList.Size = new System.Drawing.Size(145, 13); - this._llSelectedTopicsToBlackList.TabIndex = 17; - this._llSelectedTopicsToBlackList.TabStop = true; - this._llSelectedTopicsToBlackList.Text = "Добавить в черный список"; - this._llSelectedTopicsToBlackList.Click += new System.EventHandler(this.LinkClick); - // - // _cbBlackList - // - this._cbBlackList.AutoSize = true; - this._cbBlackList.Location = new System.Drawing.Point(525, 11); - this._cbBlackList.Name = "_cbBlackList"; - this._cbBlackList.Size = new System.Drawing.Size(105, 17); - this._cbBlackList.TabIndex = 14; - this._cbBlackList.Text = "Черный список"; - this._cbBlackList.UseVisualStyleBackColor = true; - this._cbBlackList.CheckedChanged += new System.EventHandler(this.SelectionChanged); - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(293, 12); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(50, 13); - this.label2.TabIndex = 12; - this.label2.Text = "Фильтр:"; - // - // _cbCategoryFilters - // - this._cbCategoryFilters.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this._cbCategoryFilters.FormattingEnabled = true; - this._cbCategoryFilters.Items.AddRange(new object[] { - "Все", - "Не скачан торрент и нет хранителя", - "Не скачан торрент", - "Храню", - "Храню и есть хранитель", - "Не храню", - "Скачиваю раздачу", - "Я релизер", - "Не скачано"}); - this._cbCategoryFilters.Location = new System.Drawing.Point(349, 9); - this._cbCategoryFilters.Name = "_cbCategoryFilters"; - this._cbCategoryFilters.Size = new System.Drawing.Size(170, 21); - this._cbCategoryFilters.TabIndex = 11; - this._cbCategoryFilters.SelectionChangeCommitted += new System.EventHandler(this.SelectionChanged); - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(164, 12); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(77, 13); - this.label3.TabIndex = 9; - this.label3.Text = "Кол-во сидов:"; - // - // _dataGridTopicsList - // - _dataGridTopicsList.AllowUserToAddRows = false; - _dataGridTopicsList.AllowUserToDeleteRows = false; - _dataGridTopicsList.AllowUserToResizeRows = false; - _dataGridTopicsList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - _dataGridTopicsList.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells; - _dataGridTopicsList.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - _dataGridTopicsList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.ColumnReport1DgvTopicID, - this.ColumnReport1DgvSelect, - this.ColumnReport1DgvStatus, - this.ColumnReport1DgvSize, - this.ColumnReport1DgvName, - this.ColumnReport1DgvAlternative, - this.ColumnReport1DgvSeeders, - this.ColumnReport1DgvAvgSeeders, - this.ColumnReport1DgvRegTime, - this.ColumnReport1DgvKeeperCount, - this.ColumnReport1DgvBlack}); - _dataGridTopicsList.Location = new System.Drawing.Point(8, 48); - _dataGridTopicsList.MultiSelect = false; - _dataGridTopicsList.Name = "_dataGridTopicsList"; - _dataGridTopicsList.RowHeadersVisible = false; - _dataGridTopicsList.Size = new System.Drawing.Size(822, 382); - _dataGridTopicsList.TabIndex = 0; - _dataGridTopicsList.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ContentClick); - _dataGridTopicsList.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._dgvReportDownloads_CellDoubleClick); - _dataGridTopicsList.Click += new System.EventHandler(this._dgvReportDownloads_Click); - // - // ColumnReport1DgvTopicID - // - this.ColumnReport1DgvTopicID.DataPropertyName = "TopicID"; - this.ColumnReport1DgvTopicID.HeaderText = "Column1"; - this.ColumnReport1DgvTopicID.Name = "ColumnReport1DgvTopicID"; - this.ColumnReport1DgvTopicID.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvTopicID.Visible = false; - this.ColumnReport1DgvTopicID.Width = 10; - // - // ColumnReport1DgvSelect - // - this.ColumnReport1DgvSelect.DataPropertyName = "Checked"; - this.ColumnReport1DgvSelect.FalseValue = "false"; - this.ColumnReport1DgvSelect.HeaderText = ""; - this.ColumnReport1DgvSelect.Name = "ColumnReport1DgvSelect"; - this.ColumnReport1DgvSelect.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.ColumnReport1DgvSelect.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvSelect.TrueValue = "true"; - this.ColumnReport1DgvSelect.Width = 19; - // - // ColumnReport1DgvStatus - // - this.ColumnReport1DgvStatus.DataPropertyName = "StatusToString"; - dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter; - this.ColumnReport1DgvStatus.DefaultCellStyle = dataGridViewCellStyle1; - this.ColumnReport1DgvStatus.HeaderText = ""; - this.ColumnReport1DgvStatus.Name = "ColumnReport1DgvStatus"; - this.ColumnReport1DgvStatus.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvStatus.Width = 19; - // - // ColumnReport1DgvSize - // - this.ColumnReport1DgvSize.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader; - this.ColumnReport1DgvSize.DataPropertyName = "SizeToString"; - this.ColumnReport1DgvSize.HeaderText = "Размер"; - this.ColumnReport1DgvSize.Name = "ColumnReport1DgvSize"; - this.ColumnReport1DgvSize.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvSize.Width = 71; - // - // ColumnReport1DgvName - // - this.ColumnReport1DgvName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.ColumnReport1DgvName.DataPropertyName = "Name"; - this.ColumnReport1DgvName.HeaderText = "Наименование"; - this.ColumnReport1DgvName.Name = "ColumnReport1DgvName"; - this.ColumnReport1DgvName.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.ColumnReport1DgvName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - // - // ColumnReport1DgvAlternative - // - this.ColumnReport1DgvAlternative.DataPropertyName = "Alternative"; - this.ColumnReport1DgvAlternative.HeaderText = "Альтернативы"; - this.ColumnReport1DgvAlternative.Name = "ColumnReport1DgvAlternative"; - this.ColumnReport1DgvAlternative.ReadOnly = true; - this.ColumnReport1DgvAlternative.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.ColumnReport1DgvAlternative.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvAlternative.Width = 105; - // - // ColumnReport1DgvSeeders - // - this.ColumnReport1DgvSeeders.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader; - this.ColumnReport1DgvSeeders.DataPropertyName = "Seeders"; - this.ColumnReport1DgvSeeders.HeaderText = "Сиды"; - this.ColumnReport1DgvSeeders.Name = "ColumnReport1DgvSeeders"; - this.ColumnReport1DgvSeeders.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvSeeders.Width = 59; - // - // ColumnReport1DgvAvgSeeders - // - this.ColumnReport1DgvAvgSeeders.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.ColumnReport1DgvAvgSeeders.DataPropertyName = "AvgSeeders"; - this.ColumnReport1DgvAvgSeeders.HeaderText = "Ср. кол-во сидов"; - this.ColumnReport1DgvAvgSeeders.Name = "ColumnReport1DgvAvgSeeders"; - this.ColumnReport1DgvAvgSeeders.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvAvgSeeders.Width = 85; - // - // ColumnReport1DgvRegTime - // - this.ColumnReport1DgvRegTime.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.ColumnReport1DgvRegTime.DataPropertyName = "RegTimeToString"; - this.ColumnReport1DgvRegTime.HeaderText = "Дата"; - this.ColumnReport1DgvRegTime.Name = "ColumnReport1DgvRegTime"; - this.ColumnReport1DgvRegTime.ReadOnly = true; - this.ColumnReport1DgvRegTime.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvRegTime.Width = 80; - // - // ColumnReport1DgvKeeperCount - // - this.ColumnReport1DgvKeeperCount.DataPropertyName = "KeeperCount"; - dataGridViewCellStyle2.Format = "N0"; - this.ColumnReport1DgvKeeperCount.DefaultCellStyle = dataGridViewCellStyle2; - this.ColumnReport1DgvKeeperCount.HeaderText = "Хранителей"; - this.ColumnReport1DgvKeeperCount.MaxInputLength = 64; - this.ColumnReport1DgvKeeperCount.Name = "ColumnReport1DgvKeeperCount"; - this.ColumnReport1DgvKeeperCount.ReadOnly = true; - this.ColumnReport1DgvKeeperCount.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.ColumnReport1DgvKeeperCount.ToolTipText = "Всего хранителей (без учёта Вас)"; - this.ColumnReport1DgvKeeperCount.Width = 92; - // - // ColumnReport1DgvBlack - // - this.ColumnReport1DgvBlack.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.ColumnReport1DgvBlack.DataPropertyName = "IsBlackList"; - this.ColumnReport1DgvBlack.FalseValue = "false"; - this.ColumnReport1DgvBlack.HeaderText = "Black"; - this.ColumnReport1DgvBlack.Name = "ColumnReport1DgvBlack"; - this.ColumnReport1DgvBlack.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.ColumnReport1DgvBlack.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; - this.ColumnReport1DgvBlack.TrueValue = "true"; - this.ColumnReport1DgvBlack.Visible = false; - this.ColumnReport1DgvBlack.Width = 40; - // - // tabReports - // - this.tabReports.Location = new System.Drawing.Point(4, 22); - this.tabReports.Name = "tabReports"; - this.tabReports.Padding = new System.Windows.Forms.Padding(3); - this.tabReports.Size = new System.Drawing.Size(1032, 436); - this.tabReports.TabIndex = 3; - this.tabReports.Text = "Отчеты"; - this.tabReports.UseVisualStyleBackColor = true; - // - // tabConsolidatedReport - // - this.tabConsolidatedReport.Controls.Add(this._txtConsolidatedReport); - this.tabConsolidatedReport.Location = new System.Drawing.Point(4, 22); - this.tabConsolidatedReport.Name = "tabConsolidatedReport"; - this.tabConsolidatedReport.Size = new System.Drawing.Size(1032, 436); - this.tabConsolidatedReport.TabIndex = 0; - this.tabConsolidatedReport.Text = "Сводный отчет"; - this.tabConsolidatedReport.UseVisualStyleBackColor = true; - // - // _txtConsolidatedReport - // - this._txtConsolidatedReport.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._txtConsolidatedReport.Location = new System.Drawing.Point(0, 0); - this._txtConsolidatedReport.Multiline = true; - this._txtConsolidatedReport.Name = "_txtConsolidatedReport"; - this._txtConsolidatedReport.Size = new System.Drawing.Size(1032, 440); - this._txtConsolidatedReport.TabIndex = 0; - // - // ConsolidatedTorrentClientsReport - // - this.ConsolidatedTorrentClientsReport.Controls.Add(this._tbConsolidatedTorrentClientsReport); - this.ConsolidatedTorrentClientsReport.Location = new System.Drawing.Point(4, 22); - this.ConsolidatedTorrentClientsReport.Name = "ConsolidatedTorrentClientsReport"; - this.ConsolidatedTorrentClientsReport.Padding = new System.Windows.Forms.Padding(3); - this.ConsolidatedTorrentClientsReport.Size = new System.Drawing.Size(1032, 436); - this.ConsolidatedTorrentClientsReport.TabIndex = 5; - this.ConsolidatedTorrentClientsReport.Text = "Отчет torrent-клиентов"; - this.ConsolidatedTorrentClientsReport.UseVisualStyleBackColor = true; - // - // _tbConsolidatedTorrentClientsReport - // - this._tbConsolidatedTorrentClientsReport.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._tbConsolidatedTorrentClientsReport.Location = new System.Drawing.Point(0, 0); - this._tbConsolidatedTorrentClientsReport.Multiline = true; - this._tbConsolidatedTorrentClientsReport.Name = "_tbConsolidatedTorrentClientsReport"; - this._tbConsolidatedTorrentClientsReport.ReadOnly = true; - this._tbConsolidatedTorrentClientsReport.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this._tbConsolidatedTorrentClientsReport.Size = new System.Drawing.Size(1032, 436); - this._tbConsolidatedTorrentClientsReport.TabIndex = 0; - // - // tabPage1 - // - this.tabPage1.Controls.Add(this._tcCetegoriesRootReports); - this.tabPage1.Location = new System.Drawing.Point(4, 22); - this.tabPage1.Name = "tabPage1"; - this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(1032, 436); - this.tabPage1.TabIndex = 4; - this.tabPage1.Text = "????"; - this.tabPage1.UseVisualStyleBackColor = true; - // - // _tcCetegoriesRootReports - // - this._tcCetegoriesRootReports.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._tcCetegoriesRootReports.Controls.Add(this.tabPage2); - this._tcCetegoriesRootReports.Controls.Add(this.tabPage3); - this._tcCetegoriesRootReports.Location = new System.Drawing.Point(1, 1); - this._tcCetegoriesRootReports.Name = "_tcCetegoriesRootReports"; - this._tcCetegoriesRootReports.SelectedIndex = 0; - this._tcCetegoriesRootReports.Size = new System.Drawing.Size(1031, 438); - this._tcCetegoriesRootReports.TabIndex = 0; - // - // tabPage2 - // - this.tabPage2.Location = new System.Drawing.Point(4, 22); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(1023, 412); - this.tabPage2.TabIndex = 0; - this.tabPage2.Text = "tabPage2"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // tabPage3 - // - this.tabPage3.Location = new System.Drawing.Point(4, 22); - this.tabPage3.Name = "tabPage3"; - this.tabPage3.Padding = new System.Windows.Forms.Padding(3); - this.tabPage3.Size = new System.Drawing.Size(925, 412); - this.tabPage3.TabIndex = 1; - this.tabPage3.Text = "tabPage3"; - this.tabPage3.UseVisualStyleBackColor = true; - // - // statusStrip1 - // - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabel1, - this.toolStripProgressBar1}); - this.statusStrip1.Location = new System.Drawing.Point(0, 518); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(1040, 22); - this.statusStrip1.TabIndex = 4; - this.statusStrip1.Text = "statusStrip1"; - // - // toolStripStatusLabel1 - // - this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(0, 17); - // - // toolStripProgressBar1 - // - this.toolStripProgressBar1.Name = "toolStripProgressBar1"; - this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16); - this.toolStripProgressBar1.Visible = false; - // - // MainForm - // - this.ClientSize = new System.Drawing.Size(1040, 540); - this.Controls.Add(this.statusStrip1); - this.Controls.Add(this.tabControl1); - this.Controls.Add(this.label1); - this.Controls.Add(this._cbCategory); - this.Controls.Add(this.menuStrip1); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MainMenuStrip = this.menuStrip1; - this.Name = "MainForm"; - this.Text = "Form1"; - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.tabControl1.ResumeLayout(false); - this._tpReportDownloads.ResumeLayout(false); - this._tpReportDownloads.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this._cbCountSeeders)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(_dataGridTopicsList)).EndInit(); - this.tabConsolidatedReport.ResumeLayout(false); - this.tabConsolidatedReport.PerformLayout(); - this.ConsolidatedTorrentClientsReport.ResumeLayout(false); - this.ConsolidatedTorrentClientsReport.PerformLayout(); - this.tabPage1.ResumeLayout(false); - this._tcCetegoriesRootReports.ResumeLayout(false); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - } -} \ No newline at end of file diff --git a/Forms/MainForm.resx b/Forms/MainForm.resx deleted file mode 100644 index 32dbdd0..0000000 --- a/Forms/MainForm.resx +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - False - - - 132, 17 - - - - - AAABAAQAgIAAAAEAIAAoCAEARgAAADAwAAABACAAqCUAAG4IAQAgIAAAAQAgAKgQAAAWLgEAEBAAAAEA - IABoBAAAvj4BACgAAACAAAAAAAEAAAEAIAAAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAALOysv+ioqL/nJyc/9LQ0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvo6f+1tbX/pKSk/46Ojv+EhIT/Y2Nj/1tb - W/9bW1v/kZGR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3Nrb/6yt - rf+dnJ3/jIuL/3Jxc/9hX2D/bWxs/4qJif+BgID/hoWF/2FeXv9nZmb/zszN/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADKyMn/oKCg/42Pjv9xcnL/Y2Ji/3Bubv+Piov/Z2Vm/z07O/8mISL/JB8f/xoW - Fv+Pi4r/U09O/0dDQv+Xl5b/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwcDA/6mpqf+QkJD/eXl5/2BgYP9gYGD/i4yK/3l3 - c/84NTL/IB4b/yEdHP8bFxT/FRMT/xkYGP8sLjD/FxgZ/56amf9aVlX/PDg3/21ta/+9vr3/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxsbH/nJyc/4SE - hP9ra2v/WFZW/5COjv+Bf3//SUdH/yEfH/8gHh//HBkV/xwVEv8cHBr/ExUV/xoXE/8bGRb/WVhY/4aI - iv89P0D/mpaV/15ZWP88ODf/QUE//5CTkf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADn4+X/4d7f/6Wlpf+ZmZn/iIqK/29wcP92dnb/o6Gh/2VjY/8iICD/HBoa/xsZGf8WFBT/FhQU/xES - Fv8YFhb/GRYV/zc4Of+mq67/FhQU/zAuLf9lYGH/paCh/5aRkf9lYWD/R0JB/0E9PP80NTP/c3Z0/7u6 - uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAANPQ0f+lpKT/l5iX/4yMjP99fHz/cnFx/11bW/85OTn/GRcY/7y6 - uv98eXn/EhER/xEQEP8UFRX/ExES/xkVFv9GQEP/p6uw/xEREv8hHh7/U1FU/5ycoP+moaL/nZqZ/6Cb - m/+inZv/oZyb/3lzc/9cV1f/SkZF/zY2NP9FSET/mpmZ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADr5+n/wcDA/5+fn/+QkJD/goKC/3d3 - d/9oaGj/VFJU/yoqLP8iJCT/RklI/3Bxc/9DQUP/x8HD/2tmZ/8PDg7/DA8Q/6ywsf8MDg//GxcZ/0hC - RP+Skpb/j42Q/5uWl/+hm5z/opuc/6KdnP+emZj/n5qZ/5uWlf+Yk5L/Y1pd/1lUVf9BQDz/OTo1/zAx - LP96enr/1tTV/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALq6 - uv+kpKT/jo6O/3Jxc/9cXFz/b29v/11eXv85Ozv/FxgZ/zg3Of9gX2X/YGNn/yovMv8JERD/DhMX/yUn - K/+3sbb/lI+R/wkEBv81NDT/kJCQ/4qIiP+Nior/m5WW/6Wfof+ln6D/oJqb/5yWl/+emJn/mpWU/5aR - kP+dmJf/mZST/4eCgf9xa2z/WVRT/0I+Pf8/Pzr/MzQw/0NHQ/+Ympn/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADMysv/pqam/5WVlf99e3r/W1lZ/2FfX/+lo6P/wb7A/zY2Nv8TExP/c3V1/3J2 - d/9IS0//AgUH/xUYHf9AQ0v/Fhof/zA2N/8VGRv/PDs//6aho/+JgoX/joiK/5iWlv+ppKX/n5qb/52Y - mf+fmpv/pZqc/6SZm/+hm5z/l5GS/5GLjP+emZj/mpWU/5qVlP+WkZD/fnl4/3FtbP9aVlX/PTk4/y0r - J/8wMCz/Ji0k/3R2df+ho6X/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+Dh/7W0tP+fn5//hoaG/21tbf9eXl7/gICA/7Kw - r/9iYGD/PDo6/4+Njf+0sbP/GBYW/xUVFf8bHiH/EhYb/w8TF/8zODj/GBwf/xcXHf9eXmL/hISF/46O - jv+alZb/pqCf/6afnv+fm5r/oJyb/56Yl/+clpX/mpaV/5mXlv+Wk5H/mZST/5mUk/+clpf/nJaX/52Y - l/+dmJf/nZiX/5qVlP97dnX/cW5q/15aWf8/Ozr/Pz08/zc2Mv84QjX/UVZV/4eIjP/V09T/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLy8n/oaGf/5WS - kv9zcXL/XFlc/315ev+opqf/hYSF/0BAQf8aGRn/Pj9D/x4cH/8ZFBT/oJqb/62pq/8VExT/Kigp/wwM - Dv8GBwr/RkhK/3h5ev9dW13/PTk7/2FbXf+alJX/oZyb/6KdnP+gm5n/oJqY/56Zl/+ZlJP/nZaW/56X - lv+blpX/nZqZ/52Zlv+YlJH/mpaU/5yWlf+blZX/mpWV/5yXl/+Yk5L/l5OS/3l1dP9wbmv/ZmJg/0dD - Qv84NTT/Ozk1/xgcFv8cIB//WFha/5mamv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAALCvr/+WlJT/fHp6/2NkYv9pZ2f/rKan/62orP9RUVX/Ih0e/zY0Nv8REhf/YmRm/xAR - D/8SFR//ExIU/xoUEv+7trX/kIyR/yckJv9vbG7/e3h6/zg1N/9RTlD/koyO/6eho/+jnaD/npea/6CZ - nP+blpX/lI+O/5qVlP+gm5r/oJua/5+amf+emZj/npmY/5+amf+blpX/mpWU/5qVlP+blpX/nZiX/5yX - lv+emZr/l5KS/4B8e/9eWln/ODQz/y0pKP9nY2L/S0dG/0ZCQf87Nzb/PTw7/xESEP8tLS3/cXNz/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtrKz/nJyc/4mHh/90cnL/VVNT/5KQkP/Lxsf/cGts/zMu - L/8qJSf/GRsf/6Sqrf8JCwz/BgoO/wcOFf8vMzf/AQYH/yElKv8UEhT/WVNT/6qkpf+emZv/nJeY/6Kd - nv+qpab/op2e/5+am/+fmZr/npiZ/6Odnv+inJ3/oJqb/6Cbmv+cl5b/npmY/6Cbmv+fmpn/nZiX/5yX - lv+cl5b/nJeW/56ZmP+el5r/oZqd/52Wmf+PiIv/Z2Bj/z46Of8yLi3/ZGBf/05JSv8sJyj/SUVE/y4q - Kf9PS0r/S0dG/0M/Pv82NDP/HRsa/y8vL/8/Pz//oKCg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADr5+n/39vd/6Wlpf+Ojo7/e3t7/1xc - XP9xcXH/uLW3/5yZm/9LSEr/IB0f/xgWGP+DgoX/Dw0P/x8cIP8KDRH/PkVI/wsOD/84O0D/FRgf/0JC - R/9HRkj/kpGT/5ybm/+knqD/n5qb/5+am/+dmJn/oJuc/6Kdnv+gm5z/oZyd/6Kcnf+fmZr/nZeY/52X - mP+fmZr/npmY/56ZmP+gm5r/nZiX/52Yl/+cl5b/nJeW/6KdnP+fmpn/mpWU/42Gif9hWl3/Mywv/y4n - Kv9AOjv/TUpG/2JfXv8+OTv/aWJl/3RwcP8aFhX/SkZF/1JOTf9MSEf/Pjo5/zs3Nv8yMC//MzAw/zIy - Mv+BgYH/5OHj/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANLP - 0P+np6f/lZWV/39/f/9kZGT/Z2Vl/6KgoP+lo6P/ZmRk/yknJ/8TERP/Pj5A/w8REv8ZHR7/EhYX/zM8 - P/8PFRj/X2Bk/xoaHv85Oj3/lJCQ/6CeoP+koqb/opyf/6WfoP+fmpv/nZiZ/6Ccnf+moaL/opyd/52Y - l/+fmpn/n5qZ/5+amf+gm5r/oJua/5+amf+gm5r/n5qZ/5+amf+fmpn/npmY/56ZmP+gm5r/oJua/52Y - l/+FgH//VlFQ/0pFRP9HQkH/VlFQ/09LSv9JREP/UUxL/0xHRv9OS0b/UExJ/1xXWP+3srP//Pv7/1dT - Uv8+Ojn/NDAv/09LSv9OSkn/Pzs6/zg0M/81MzP/MjAw/05KS/+ioqL/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAwr2//5iXmf+HiIj/bGxs/1tYWP+Kh4j/uba3/2pnaf8vLzD/ISAh/xwd - Hf8ZGhr/GRwc/w0QGP88P0b/ExYb/2dpbv8bHiH/Kiwv/4KEhv+OjI//oJyf/6Cbnf+spqb/paCh/6Wf - oP+jnZ7/p6Cg/56ZmP+dmJj/oJyb/6GcnP+jnZ3/n5ma/6GcnP+inJz/oZuc/6Cbm/+hm5z/n5qa/52X - mP+gm5v/n5mZ/56YmP+fmZr/pJ6e/355ef9aVFX/VVBP/15aWf9cV1b/X1hX/1xUVP9bUlH/UkpJ/1NM - S/9TTUz/UUxK/1FNS/9STUv/UEpK/3VvcP/Szc7/UkxK/0tHRP9IRUH/Uk1K/0lEQ/8/Ozr/Ozc2/zc0 - M/80MTD/OTY1/319ff/b2Nr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL69vf+tqqz/lZWU/317fP9WUlf/eHV3/7y8 - vP+WlZb/Pj0//xIRE/8UEhT/Tk5S/xAUF/8pLDD/FBgb/xcbHP9gZGX/BwsQ/w4RFv9hYmb/h4eL/5uZ - m/+cl5n/p6Kk/6Sfof+loKL/paCi/6WfoP+jnZ7/n5ma/6Kcnf+Zk5T/o56d/6Cbmv+inZz/op2c/6Gc - m/+hm5z/n5ma/6GbnP+fmZr/oZuc/56Ymf+emJn/npiZ/6qkpf+SjI3/cWxr/1JNTP9ZVFP/WlVU/1tW - Vf9fWFj/XFdW/19XV/9iWlr/XlZW/2BWVv9iWlr/Z2Jh/1pVVP84MzL/WFNS/1NOTf9PSkn/UEtK/1BL - Sv9QS0r/SkhH/01KSf8xLCv/UEtK/0M/Pv8/Ozr/Ozc2/zczMv82MzL/VVVV/6qqqv8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADm4uT/q6mp/5mX - l/+Afn7/Yl9h/2ZjZf+moaL/vLm7/2JhZf8TDhD/GhYX/15jaf8VGh//NTk+/wsOE/8UGB3/PkZK/wwR - Ff8LEBX/Kyww/4eFh/+tra3/m5qc/6Wiov+ln6D/oJuc/6CbnP+oo6T/qqWm/6Oen/+loKH/pJ6f/6Gb - nP+emJn/oZuc/6Sen/+jnp3/o56d/6Cbmv+hnJv/op2c/6GbnP+gmpv/nJaX/6Sen/+knp//nJeW/314 - d/9PSkn/VlFQ/1dSUf9bVFH/XFVS/1pTUP9ZUk//WlNQ/2RYWP9iWFj/Z2Bf/2VgX/9aVlX/Ozc2/yAc - G/8PDQz/FRMS/yIgH/88Nzb/Yl1c/1BLSv9TTk3/S0ZF/01KTP9NTU3/Tk9S/z06PP9MSkr/SERD/0M/ - Pv89OTj/ODQz/z06Of81NTX/g4OD/+vo6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADh3uD/kZGR/3Fxcf9kYmL/ioiI/7Kwsf+Kh4n/NDI3/yAcHP9TU1b/EhYb/0pN - UP8ZFRb/Ehgf/wsSGf8oLjP/DA8S/xQYHP8WGh7/CQ0R/ywuMf9bWVz/jYuM/6aiof+moqH/oJya/6ml - pP+inJz/op2e/5yXmP+gm5z/pJ+g/6Oen/+knp//pJ6f/6Odnv+jnZ7/n5ma/6Cbmv+hnJv/oJua/56Z - mP+fmpn/oZyb/6Oenf+Ae3r/YFta/1dSUf9aVVP/VlFP/1hUUv9VUU//WVVT/1lSUf9aU1L/YVtY/2BZ - V/9jXFn/XlRU/0U+Pv8gGxr/FxIR/xUREP8cGhn/MS8u/0A9PP9OTEv/TUpJ/01IR/9LRkX/VlJR/1FM - S/9OSUj/QkBC/2prb/96fIL/l5aZ/y0rKv9MSEf/R0NC/0A8O/84NDP/hICA/zAwMP9aWlr/rKys/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADo5Ob/sK6v/2Rh - Y/8qJyn/MjEz/xgYHP9BQ0f/ExMV/w0RFP8ECA3/Y2pt/w4QE/8mKS7/W19k/4CBhP9RUVL/UE9P/4OB - gv+no6X/o6Gh/6akpP+joaD/m5eV/6Ccm/+cmJf/nZub/6Cdn/+jnp//pqKh/6WhoP+jn57/o5+e/6Se - n/+gmpv/oJqb/6Cam/+gmpv/n5qZ/6Wgn/+hnJv/jYiH/21oZ/9bVlX/W1ZV/11YV/9fWln/XVhX/1dS - T/9ZVFH/WVRR/15ZVv9cV1T/W1ZX/1tWVv9IRUL/LCgn/xUREP8QDQz/GhcW/zMvLv89OTj/ODQz/yso - J/8hHh3/LCcm/zk0M/9STUz/V1JR/0tGRf8wKyr/W1ZV/1FMS/9JRUT/bWtv/7Kwtv+uqav/Qz89/1RQ - T/9MSEf/Qj49/z87Ov9XU1L/Q0ND/zo6Ov+NjY3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAObi5P9dWlv/GRkZ/w8SFP8gIyb/Fhod/xkcHf8PExj/Gh8k/2xzef8REBb/Kyov/09Q - VP+HiIr/r66u/6emp/+npqb/qaan/6qlpv+noqL/pqGi/6Wgof+ZlJX/npiZ/6GbnP+jnZ7/op2d/6Od - nv+knp//o52e/6WfoP+hm5z/o56e/6Sen/+jnp7/opyd/6CbnP+fmZr/oZyd/2FfX/9vamn/WVNQ/1tT - Uf9dVlT/XFRU/1xWUv9UTkv/NTEw/0M+Pv9YU1P/YFpW/2JdXP9bXF//Wl9h/5OQlv/U1Nn/cG9z/y4s - LP85NzP/Uk9L/1BMSv8qJiT/Ih0c/yYhIP8jHR3/Ix8e/yUhIP8jHx7/Ix4e/zYyMf8sJyj/JiEi/x8a - Gv8hHBz/Yl1e/1JOTf9VUVL/TUhK/0lFRf9LR0X/MCwr/09LSv9HQ0L/QDw7/zYzMv9bWFf/ODY1/2Rj - Y/+ura3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5eHj/xsXF/8RERH/FhgZ/xQX - HP9vc3f/Cg0R/yMnLP8uMTb/foGG/7e1u/+tqq//rKit/6Sho/+rpqf/p6Kj/6ijpP+noqP/op2e/6ei - o/+qpab/oJuc/5uWl/+knp//pZ+g/6Kcnf+jnZ7/o52e/6GbnP+jnZ7/oZuc/6qkpf+inJ3/opyd/56Y - mf+emJn/npma/6Kdnv+LiIj/Pjw8/1hTUP9ZVFH/XVdU/1dPT/9LQ0P/TEVC/0M+O/8ZFRT/FhES/ysm - J/9lXl3/KyQl/zk8Pf/p7vH/9e71/3l1ev8pKCn/MCwr/05KR/9UUEv/UUxJ/yMeG/8gGxr/HxoZ/yAa - G/8kIB//IBwb/yAcG/8dGRj/HhoZ/xwXGP8dGBn/Ix4f/yolJv8gGxz/SUVE/1dTUv9XU1L/R0NC/09L - Sv89OTj/VVFQ/01JSP9GQkH/PDg3/zs3Nv8zMTD/QT8//5GPj/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADV0NT/FRET/xkYGP8jJCX/Dg4S/0pOU/+goqj/p6So/62qrP+spqf/paOl/6ek - pv+in6H/sKut/6iipf+jnp//pqCh/6Kcnf+gm5z/op2e/6Kdnv+kn6D/oZyd/6Kcnf+hm5z/oZuc/6Kc - nf+jnZ7/pJ6f/6WfoP+inJ3/p6Gi/354ef+emJn/pJ6f/5uWlf9saGf/U09O/0hEQ/9aVlX/WldT/1lV - VP8lIyP/S0ZI/0hDRP9cWFj/bWlo/zw4N/8RDQz/HBcY/0lERf9NQUP/HBka/2doZv9jWlv/UElG/yol - If8bFxb/PDg3/1BMS/9IQ0D/HxoX/x4ZGP8fGhn/HhgZ/x8bGv8eGhn/HRkY/xsXFv8fGxr/HRgZ/x8a - G/8kHyD/KSQl/x8aG/8hHRz/IR0c/xcTEv9QTEv/S0dG/01JSP89OTj/Uk5N/0hEQ/9BPTz/Ozc2/zQx - MP82NDT/ZWNj/7u6u/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyYnf81MjP/enh3/6+s - rf+mpaX/mZmc/6Oio/+koKL/qaSl/6afoP+koJ//pJ+g/6Oen/+jnJ//pZ6h/6Oen/+jnp//o56f/6Oe - n/+hnJ3/oZyd/6Gcnf+hm5z/oZuc/6Odnv+inZz/n5qZ/6ahoP+CfXz/aGNi/1pVVP9dWFf/YFta/396 - ef9QS0r/VVFP/1RPTf9XUlD/W1ZV/1pUUf9kYVr/REND/0NESf+kpan/vbu9/3Z0dP8pJSb/UU1N/2Rf - Xv8RDQz/PDs7/21gYf8RDAv/WFVS/2BYVf9XUk7/X1tY/yQgHP8fGxr/IR0c/zUwLf8gGxj/HhkY/yAb - Gv8hGxz/Hxsa/x0ZGP8eGhn/HBgX/x0ZGP8dGRj/Hxsa/x4aGf8iHh3/HRkY/yMfHv8bFxb/GhYV/0M/ - Pv9TT07/TUlI/0A8O/9YVFP/TkpJ/0hEQ/88ODf/ODU0/zIwMP8/PT3/j4+P/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAq6es/6Gen/+amJf/mZaS/5iUk/+YlJP/n5ua/6Kcnf+vqqv/pJ+g/56a - mf+koJ//o56f/6Weof+knaD/pJ+g/6CbnP+jnp//oZyd/6Gcnf+dmJn/paCh/52Ymf+tp6j/iIKD/3Br - av9hXFv/XFdW/19aWf9gW1r/XllY/15ZWP9bVlX/XFdW/1xXVv9dWlb/XVhV/11XVP9dVlP/XlhT/2Ng - Wf9OTlD/hYqT/32Ah/+LjJD/vby+/0A/Qf9EQkL/ZmJh/z87Ov87Ozf/aF1b/1BLSP8mJyP/aWdl//z9 - /f/s7Oz/jomK/x8aG/83MjH/My4r/yAbGP8eGRj/HxoZ/yAaG/8hHRz/Hxsa/xoWFf8fGxr/IR0c/yEd - HP8iHh3/Ix8e/yEdHP8jHx7/GxcW/yIeHf8aFhX/VlJR/1hUU/9LR0b/T0tK/z05OP9STk3/RkJB/0I+ - Pf85NjX/MzEx/zAuLv9kZGT/1tPU/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChnZ7/npmb/6Gc - nf+jnp//j4uK/52ZmP+jn57/op6d/6ShoP+loaD/pJ+g/6Oen/+noqP/paCh/6Gcnf+kn6D/oqCf/6aj - ov+cmZr/qaKn/5iRk/98dnf/YFtd/2BbXP9fWlv/XVda/2plZv9RT0z/Pzw7/xcWGP8rKSv/JiYm/x4c - G/84Njb/Y19f/1pXU/9dWVj/X1lY/1pRUf9nXVz/Uk1K/0tLTv9zeH3/WFxh//7////y8/X/p6uu/2Vp - bf9iX2H/Ylpa/0pCPv9oX1z/a2Rh/wsHBv9ybm3/5OLl/8vN0f/l5er/REBB/zUwLP8rJiL/Ih0c/xwX - GP8aFxb/IB8a/yEcHP8pJST/JCIh/x0aGf8cGBf/HhkY/xgWFf8aGBf/KCgi/xkZFP8bGBT/IR8e/yQg - IP9iXlv/X1lV/1RPSv9PSEb/QTw6/2BcW/9RTUz/R0NC/z05OP87Nzf/NjIx/0RBQP+bm5v/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJOOkP+jnqD/oZyd/5uWl/+gnJz/n5ua/56amf+hnZz/pqKh/6Wh - oP+loKH/p6Kj/6Kdnv+inZ7/o56f/6Sfof+bl5f/jIiH/11YWP9ZU1X/W1NT/2ZhX/9gWlv/5OHj/3Vy - df9MSE3/Hhwc/yMiIf8YGRn/dXZ5/yIkJP9LTEr/ODU1/yUjIv8XFRT/S0ZF/1tWVf9lYF//XFdW/1xY - V//Avbz/U1NX/01QV/9yeH//0dXa/8THy//i5+r/vsHF/4B8ff9VSEb/Z15a/2VeW/9pYl//VlFQ/ysn - Jv+WkpP/xcHG/2FdYf+Ig4P/NC4q/zQxLP8bFhb/Ih0e/x4cG/8cHBf/HBcY/xwYF/8aGBj/GBYW/xkX - Fv8lISP/FxUb/xsZIP8tLS3/IR8e/yEeGv8aGBj/Hxob/2NcXP9hWFX/YFpV/1BKR/9TTkv/Pjo5/1NP - Tv9KRkX/Qj49/zMvLv9EQD//ODU0/3BwcP/X1Nb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa1tn/ko2O/6Cb - nP+cl5j/n5qb/56Zmv+empn/n5ua/5+bmv+loaD/paGg/6Oen/+kn6D/npma/4+Ki/9uaWr/XVZZ/2Jd - XP9lX1v/ZGBb/2NeW/9VUUz/HRoV/y8tLP/19/f/+Pv+//bz9/8nKiv/fICC/xkeHv8nKSz/Ih8f/01L - Sv9CQD//HRsa/x0bG/8xLjD/PDk7/yQjJf8fHyD/PUBA/zUzM/9fX2P/TVJY/2Vsdf+mrbf/yMzS/7i8 - wP+Ul5n/ZmFg/15UTf9jW1f/YltY/2RdWv9oY2L/GxYV/zQvLP8wLCv/LCko/xcTEv8pJST/LCgo/x4Z - Gv8aFhf/GRcW/xcWEv8bFxb/GRcW/xkXF/8RERH/Gxsb/ywsOv8qLEH/Kys//x8fKP8mIyT/Hxob/xoX - GP8dGBr/Y1xd/2BWVv9cVVH/VU9M/1FMSf88ODf/WVVU/1FNTP9FQUD/Pzs6/1VRUP8yLy7/RERE/5aW - lv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKilp/+Uj5D/mJST/5mUlf+dmJn/n5qb/5yYl/+bl5b/nZmY/6Sg - n/+WkpH/enV0/2NeXf9gW1r/YVxb/2RfXv9nYmP/Y1xa/2FZVv9kYF3/cHBv/35+ff9TVFL/X2Fj/+/x - 9f/w8/b/7Ort/4qNkv+rsLb/V1tg/zw8Qv8fIB7/Hh8f/xscHP8eICP/JCQo/1NWW/97f4P/V1xf/05S - U/9HS0z/Liwv/zEwMv9ERkj/REhN/y40O/8bHSH/OzxA/0E/QP8+OTn/W1RO/1xYU/9iW1j/ZF1a/2lh - Yf9YUFD/LSgl/yQfHP8aFRT/FxMV/yEiJf8eGx//HBoa/xcVFP8WFBP/GRUU/xgWFf8ZFxf/HBsd/xkb - G/8mJS7/LCxF/ycpTP8qLEv/Hhwp/ykmJP8aFxT/FRMT/x0YGf9eV1f/YVhV/15YU/9cVlP/UUxJ/01J - SP9BPTz/VFBP/0pGRf9BPTz/NzMy/zMwL/81NTX/c3Nz/+bi5P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAm5mZ/5iT - lP+alpX/m5aX/5aRkv+oo6T/29bX/4SAf/9eWln/X1ta/2JeXf9gW1r/Y15d/19aWf9bVlX/X1pZ/2Fh - Xv9PS0f/XlZV/yIfIv/u8/f/7fP3/4CDif90eH7/5unu/8LCxv/My8//zM/X/8jR2v/X3uX/Ki8w/w8T - E/8tMTL/dXp+/+Hm6//DydH/wsvV/8LM1f97gof/k5eb/0NGSv86PUH/IiAi/xsYF/8aGBj/FhYX/xcW - FP8ZFxf/GRQW/yYhI/9OSkn/WlZS/1pVUv9jXFn/Zlxc/2phYf8lIR7/Ih0a/xMQEP8QEhf/QEZP/xUV - HP8VFRX/GxoW/xgWFf8ZFRT/FxUU/xYWFv8bGhz/GBgd/yYnMP8pKkb/JihP/ycpS/8WFB3/HxoR/ywp - JP9NS0j/QT07/19ZVP9jW1T/X1lU/1tUUf9VUE3/UExL/z87Ov9YVFP/UU1M/0VBQP86NjX/NzQz/zEx - Mf9ISEj/np6e/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjnp//mJaW/6CbnP+Oion/ZWBg/19aWf9kYF//YFta/2dh - Yf9kX17/XVlY/1xaWf9GQkH/IBsa/15WVv9gV1f/ZFtb/2hjYP8mIR7/KCQj/2RgX/9jZm3/OjlC/5CN - lv/i4+n/2eDk/+fp6v/3+Pz/7PL4/9DZ4//T3ef/0tvk/6Wut/+7xM7/zdbg/9Ha5P/M2OT/yNHb/7C4 - wf9MUln/WF1g/0pHUP8fIh//ICUh/xoXGf8ZFBX/Gh4Z/xIWFf8aGBj/HBcY/y8pKv9VTU3/XFJS/2NZ - Wf9hWVn/Y1tc/zkzNv8WEQ7/HxoX/wkQEP8uNE3/NzZE/w0MD/8fHBj/GRYT/xYWFv8WFRH/FRYU/xcZ - Gf8UGBj/Jyow/z89VP9LS1n/OzhA/1NMTf9RSkf/WVVQ/1xYU/9eWlX/W1dS/1xYU/9eVlb/WFNS/19a - Wf9STk3/T0tK/0I+Pf9YVFP/SERD/z87Ov86Nzb/MzEw/zg2Nf92dnb/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA49/h/6Cb - nP8qJyb/KSQk/2ZiYf9gW1r/ZF1c/15bWv9hXVz/ZV1d/2BbWv9fW1r/NzU0/y0pKP9WUVD/dW1t/2Zc - XP9GP0D/IR0d/0pFRv9oZGT/UUpK/0A7Q/+Kho//VFJb/8LHzv/L19v/zdTa/9PZ4v/R2uT/ytPd/87W - 4v/S2+X/ztfh/9Ha5P/L1N7/09zm/87X5P/K1N7/vcXO/3qCif+Tl5z/PT5E/z9EQ/8jJyv/KCYr/x8c - GP9PUFT/Ghka/xQTE/8WEhH/Pjo4/1NJSf9ZT0//XVRU/2BYWP9kXV7/LCcn/x0XFP8WERH/CQ8R/zo8 - Wv9TUl3/FxQW/x0YFf8fGxj/FxQU/xcTEv8cGhn/JyUl/yAfIP8ZGR3/EA8a/yMgJf8pJiP/Qj06/1dR - Tf9dV1L/W1RQ/1pTT/9cVVD/XVZR/1xUVP9ZVFP/V1NS/1BMS/9QTEv/Pzs6/1pWVf9NSUj/REA//zUx - MP81MzL/MzEw/0lJSf+qqqr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADTztD/ZWBh/xUREP8aFhX/XlpZ/3x4eP9RS0z/JyUk/2Je - Xf9jW1v/ZWBf/0RAP/8dGhb/UU1J/1NOS/9VUE3/UElG/0E8Pf8XFhb/Hx4g/yckJv8uLCz/VU5V/2Be - Y/94d4H/tr/H/7vIzv9TYG7/vcfV/8zV4f/T3Ob/zdbf/9DZ4v/R2uP/0Nni/9Lb5P/O1+D/z9ji/8vV - 3//Ezdb/uMHJ/0tTWv9cZGj/RElO/zU2RP88OUP/IB8Z/0VGTP8REBH/FxUV/xkVFP9APTn/UEtK/1NO - Tf9YUFD/WlJS/1dRUv8kIB7/IBsZ/xINDv8RFBb/o6C8/yMcI/8pIyT/HxoX/zItKv9HQUL/Vk5O/1RP - Tv9YU1L/Ih0d/ygjI/9SS03/V1JP/1ZQTP9XT07/V09P/1xTUP9YT0z/WVBN/1tST/9YUE3/WVFR/1lU - U/9bVlX/e3Z1/0xHRv9MSEf/SkZF/09LSv9FQUD/Pzs6/zc1NP80MjH/NjY2/4ODg/8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFlX - V/9OTEz/SUZC/1xZVf9fW1r/aGVl/4iFhv+5t7b/ZGBf/2tkY/9mYF//GRYV/1dST/9hXFn/Y15b/1pV - Uv9bVVL/YFxb/5uZmf9ERUX/WFdb/y4pLv9NR03/ZGRp/+Xs8P/S3eT/yNTc/7PBz//U4O3/zdfj/9DZ - 4//R2uP/0Nni/9Ha4//Q2eL/ztfg/9DZ4v/L1t7/y9be/8bR2f+8xs7/maKr/5eipv8/Rkr/RkdT/zM0 - QP83Oz7/Gxkc/xUTE/8WFBT/FhQU/xYUEv8lIiH/MC0s/0tGRf9WUlH/X1dW/xgVE/8iHx3/DAoK/xoc - GP9MRln/Vk9P/1JMSf9ZVVL/Pzs6/yciI/9LRkX/W1NT/1lRUP9hWVb/Jh4b/zUxLP9OSUT/U01I/1NN - S/9VUE//Vk5N/1FJSP9RSUj/UUhI/1lRUP9VUVD/W1ZV/6Oenf9fWln/WVVU/0tHRv88ODf/V1NS/0dD - Qv8/Ozr/NzU0/zY0M/8yMjL/VFRU/6qqqv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5+Pl/2tpaf9oZF//Y2Bc/15cXP9WVFb/1NTU//r5 - +P9kYF//bWVl/1FLSv9BPTz/X1pX/2NfWv9APDf/V1NO/2FdWP9jXlv/SUVE/zc3N/+koaP/iISJ/0tL - Tv/s8fb/1N/j/8/a4v/M1d//0dzk/8jT2//S3uT/1N3m/9Xe5//T3eT/1d/m/9Hb4v/b5ez/ztjf/8zX - 3//M19//ydTc/8jT2//BzNT/Rk1V/2lvbf9CSEr/MzlL/x4kN/8cHBr/EQ8O/xUTE/8UExX/ExIU/xQV - E/8cHBr/MS0s/09LSv9eWVn/LCcn/0VDQf8SExH/FxoP/zIqMf9YUkr/JiMe/zEvLv8lIiH/QDw7/0tH - Rv9NSEf/VE1K/1VPSv9WUEv/EQ4N/0dCQv9FQD//SkVD/11WU/9cV1b/WlVU/zMuLf8aFRT/LCcm/0ZC - Qf9qZWT/dnFw/11VVf9PSkn/TkpJ/09LSv9TT07/UExL/0VBQP89Ozr/OTc2/zMzM/86Ojr/g4OD/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGlkY/9qZGX/ZV9g/0lFRP9JREX/YFta/2VgYP9mYWL/zcvN/9zZ3v+BfoH/bGtr/ysn - Jv9STEv/Z2Fc/1VRTP9JREH/jYeI/3NvdP9fYGf/7vT4/9Pd5P/W3+j/1uHp/9Tf5//W3+j/09zl/9Lb - 5P/V3uf/1N3m/9vh6P/Y4Of/1N3k/9fi6f/O2uD/1dvk/87V3v/T2+T/z9jh/8HM1P+dpK3/i5ed/01T - V/9MT13/JjhV/xcVGf8jISP/FhQU/xQSEf8WFBD/FBUS/xUVFf8UExX/KCMl/zs0N/9KRUH/SlBU/1tH - Sv9SU0b/WVZN/0lEQf89OTj/EA4N/xMUEv8vLi3/Uk5N/yklJP9PSkn/TkpJ/09LSP8pJyb/FRMS/yUj - Iv8vKyr/U09O/2dhYP9jW1v/XVdX/1ZQT/9STEv/VlFQ/1hTUv9WUVD/WFNS/1RPTv9WUVD/SURD/zk0 - M/9XUlH/RkJB/z46Of87Nzb/ODQz/zUxMP9XVVT/xsTF/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5uLk/21naP9nYWL/ZmFg/2Vg - X/9kYF//W1ZW/zc1Nf/5+Pv/1dba/+bl5/+wsLD/Mi4u/0xHRP9jXlv/SkdD/z05N/9kX2D/X15i/+ns - 8P/U2+P/1N3m/9fg6f/X4ur/0t3l/9Pc5f/V3uf/1N3m/9DZ4v/W3+j/2uLp/9nh6P/Y4ej/2OLp/9Lc - 4//V3uf/zNXe/9Pd5v/b5u7/yNLc/6+4xP9GVFv/fX+E/0xMU/8wPEz/ERAT/x8dIP8YFBX/GBQU/xcT - FP8VExL/FBMT/xcVFP8aFhb/HBcY/x8YGf8eIBn/XltU/zxGXf9CPEX/TkdH/1FMS/8yLi3/IR0c/zIu - Lf9STUz/RD8+/0xHRv9MSEf/SkZF/0lEQ/9LRkX/RUFA/0pFRP9KRUT/T0dH/1BISP9SSkr/UUlJ/1JK - Sv9QS0r/UUxL/1NOTf9VUE//VE9O/09KSf9NSEf/R0JB/1ZRUP9KRUT/REA//z46Of81MTD/NjIx/z06 - Ov+CgoL/6OXn/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAjouL/2hjZP9kYF//Yl1c/y4rKv8ICgn/GRkZ/52foP/Q1dX/6efo/0pH - SP8dFxf/Qj08/09KR/9APTn/NzQy/4OAgP+SlJn/19zl/9bd5v/U3eb/1d7n/9Pe5v/Q2+P/09zl/9fg - 6f/T3OX/1t/o/9Pc5f/Y4Of/1t7l/9bg5//V3+b/0tzj/9Ld5f/L1t7/zdjg/8nV3f/H0dr/s7vI/4ON - k/9ydn3/VVJV/xMWEf8VFRT/FBMT/xgYGP8gHyH/ERAT/xQSE/8VERD/GBQR/xkWEv8YFhX/Ih0e/y8s - Lv89SlX/HC92/0hET/9PR0j/TERE/0lCQv9IREP/S0ZF/0xERP9QSEj/TERF/01GRf9JQkH/S0ND/0lB - Qf9JQUH/SkJC/0pCQv9JREP/SURD/0lEQ/9JREP/SURD/0xHRv9OSUj/TUhH/09KSf9STUz/TUhH/1NO - Tf9JREP/Mi0s/1JNTP9FQUD/QT08/zg0M/86NjX/NTMy/1dXV/+8u7z/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAamho/2pl - ZP9fWFj/EA8O/wkKCP8QEQ//FxgY/xMTE/8gHBv/JiIh/yYiIf9CPj3/OTU0/zMwLP8+PDr/NzY4//P4 - +v/S2+T/1Nvk/9Td5v/S2+T/z9ri/8nU3P+EjZb/3OXu/9jh6v/W3+j/09zl/9Te5f/a5Ov/1d/l/9bf - 5f/V3eX/4uvw//L4+v/EytD/oaes/3qBhv9XWmT/U1da/05SYf8LER7/HRsT/xkYFf8YGRf/FRUV/xAS - E/8fICX/FhYZ/xQSEv8WEhH/ExIU/w4TF/8WHRv/LzRX/ygxa/8YK3b/R0hB/01IRv9PS0r/UkxL/1NL - S/9QSEj/S0dG/0lFRP9FQUD/REA//0M/Pv9EPz7/RD8+/0M+Pf9FQD//RUA//0ZBQP9GQUD/RkFA/0ZB - QP9FQD//R0JB/0dCQf9IQ0L/SkVE/0tGRf9MR0b/UUxL/09KSf9IQ0L/SkZF/0dDQv9CPj3/Pzs6/zg0 - M/82MzP/Ojo6/42Njf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDwcL/Z2Ni/19XV/8ODAz/DgwL/wcFBP8YFhX/LCop/zk1 - NP8rJyb/HhoZ/yUgIf8rJif/JyUl/1pYWP+vrrD/2+Lp/9Tg6P/V3uf/1N3m/9Pc5f/Q2+P/w87W/5Kb - pP/Cy9T/uMHK/9jh6v/T3OX/09/l/9Te5f/W3+f/4+zz/7O5vv8EBwr/SkpM/4KChP9tamz/Z2Jk/1xc - W/9FQkL/NTxW/ztEZ/8dICT/HBsb/xgXGP8VFxr/GBwd/xccHf8QFRj/FhcW/xkZGf8YGyT/HiU1/yEn - Q/8aNnD/Iitu/yg0X/8mICb/MjAv/0A9PP9EQD//Pzs6/zw4N/84NjX/ODY1/zY0M/81MzL/MzEw/zcz - Mv86NjX/Ozc2/z46Of9BPTz/QDw7/0M/Pv9EQD//Qz8+/0A8O/9FQD//Qj08/0VAP/9GQUD/R0JB/0tG - Rf9NSEf/UEtK/0pFRP8vKin/VFBP/0dDQv9CPj3/OTU0/zYzM/8xMTH/Xl5e/6qqqv8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABxbG3/a2Vm/ywpKP8MDQv/BgkH/yIfHv9oYGD/Y19e/x4aGf8aFhX/U05N/1dSUf8oJCP/Ozk8/+Hl - 6v/c5Ov/1d/m/9Pd5P/U3eb/1d7n/8PM1f+hqrT/sLnD/5WeqP/Y4er/1+Ho/9fg6f/Q2eb/1eDn/+Dp - 7P8nKSr/XVpe/2VhY/9xbG7/cWls/4F4e/99cnf/RERP/z82Qf8bJzP/Hio1/yseLP86O0z/CxIc/xAY - F/8XGRr/IBgh/xwmJv8hJDP/Ki9O/yszXP8vLlP/Ji9b/x4zaf8ZKFn/Iig//xkTEv8SFRP/FRYU/xUW - FP8TERD/EhAP/xMREf8SEBD/ExER/xQSEv8VExP/ExEQ/xcVFf8VExP/GBUW/xkWGP8hHB3/JB8g/ygj - JP8wKyz/NzIz/z47N/9APTn/Pzw4/0A9Of9EQT3/R0RA/0pFQv9STUr/R0I//0tGQ/9MSEf/TEhH/0RA - P/8/Ozr/NjIx/zY0M/9FQ0P/jY2N/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvaWr/ZWFg/xANDP8KCgj/BgcF/0VB - QP9aVlX/KiYl/x0ZGP9AOzr/PTg3/zo2Nf82NTj/6e3y/9ri6f/b4+r/0dvi/9Xe5//N1t//sbrD/8fQ - 2v+2v8n/nqex/9DZ4v/V3+f/0tvk/9Xe6v/k7fX/BwsO/01LTf9VUVP/WFBT/4yFiP+rpKf/RkFE/ykl - Jv8vIyD/XnB9/xIfPP8hGzL/JDEz/xkbGP8jIjH/KSg5/xIWH/8SGCP/HR8y/yooP/8lLU3/JTZj/x4w - Wv8dJ0//HypS/zY+Xf8FBhT/DQ4O/w4REP8QERD/EBAP/xUTE/8TERD/EhAQ/xMREf8QDg7/EQ8P/w8N - Df8SEA//EQ8P/xIQEP8TEBL/ExAS/xQSEv8UEhL/FRMT/xYUFP8XFRX/HRgY/yIdHf8qJib/NTEx/0I+ - PP9DQDz/S0hE/05JRv9OSUb/S0ZE/zIuLf9QTEv/SUVE/0M/Pv86Nzb/NjQz/zUzM/9kZGT/u7q8/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAIuJif9iXl3/RkJB/xEPDv8JCgj/CAkH/xgWFf8bFxb/NTEw/1FNTP9HQkH/JyMi/2xv - cv/h5er/2uLp/9ff5v/W4Of/0tvk/5ukrf+yu8T/t8DK/663wP+cpa7/1+Dp/9Xe5//U3eb/2ePr/wsO - FP9NTU7/Gxga/0I9P/+HfoH/mpOW/314ev9zcHL/goOE/3l3df9oaHb/Rltw/y9Waf8bGCv/GB4r/yEe - M/8bFyP/EBUa/y00RP8kLUT/JiMq/yYjLP8lJz3/MDJP/0BKZf9NUmX/SUhT/1FSWv9kZ27/WVpe/0lK - Tv9OTlL/NDM2/zM0Nv8yMjL/NTU1/zk5Of8tLS3/Nzc3/zo6Ov80NDT/Gxsb/xQUFP8ODg7/Dw0N/xEP - D/8SEBD/ExER/xQSEv8XEhT/FhET/xYTFf8YFRf/GxkZ/yckI/85NTT/RUA//1hTUv9GQkH/SkZF/1FN - TP9KRkX/RUFA/z88O/83NTT/RkRE/z4+Pv+RkJL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhmZf9oZGP/GxcW/w4M - C/8LDAr/DgwL/xwaGf8kIiH/NjIx/zs3Nv9DQUD/eXt+/9zj5v/X4ej/1+Ho/9fh6P/U3eb/rba//7S9 - x/+xusT/v8jR/8/Y4f/Z4uv/1d7n/9Pc5f+5wsb/DhAT/29sbP8KBQb/FBIU/yciJP97dnj/9vT2//f4 - +P/19/j/8P7+//r9/v/++vf/9fP5/423zv+Gkrf/HSw5/xAXHv8kIi7/IBss/xsgRf8ODyL/BQ8g/zdM - Yv8UK0D/BAgU/wAAAv8GBgb/AQMF/wAABf8AAQL/AAMH/wUGCv8GBQn/BAEG/wUFBf8CAgL/AwMD/wUF - Bf8DAwP/BgYG/wMDA/8ODg7/CgsJ/xscGv8aGhr/Gxsb/xISEv8QEBD/Dg4O/xEPD/8UEhL/FBIS/xUT - E/8WFBT/FxUU/xgWFf8kIB//R0NC/01JSP9NSUj/MCwr/1BMS/9JRUT/RkJB/zg2Nf/e3Nz/MTEx/2dm - aP/Lycv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA0tDQ/2NjYf9eWln/EAwL/wwJCP8MDQv/FhUU/x4cG/84NDP/HhoZ/yYk - Iv+Ymp3/4Ont/9fh6P/V3+b/1uDn/9fg6f/Z4uv/ztff/4iSm//h6/L/1N7l/9Td5v/U3ef/1d7n/1FY - W/9ERET/amVk/3p1dv9oZWb/hISG//v7/f/4+Pr/6uvs//Py9P/v7fD/cnZ2/yIiI//G0dH//Pr7/83Y - 3P9VXob/DRxA/w4WKv8mJTv/IzJI/x4qOP89T17/EyEx/ycpMf8oJij/QUZJ/15kaf9+gIj/bm51/0xR - Uv87QED/P0FB/yQmJv8iJib/Jykp/zEzM/8/QUH/QkRE/0NHR/8mKCn/ExUW/w0PD/8DBAT/AQMD/wIC - Av8DAwP/CwsL/ycnJ/8bGxv/FxYU/xAODf8QDw3/ERAO/xIREP8UFBT/FRMT/yAeHv8YExT/TkpK/0hE - Q/9LR0b/TEhH/01JSP9FQkH/PDo5/3Rycv85ODj/QkJC/5qYmf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAe3l4/2hj - Yv80LCz/FBAP/w8MDv8NCgz/HRsb/x4cHP8jISD/Ih8h/4aIi//g5u3/2OLp/9ni6P/X4ej/1uDn/9Xf - 5v/X4ej/2OLp/9fh6P/W4Of/1+Do/9Lb5P/T2+T/ISQq/3Vzdf93cXL/eXN0/2loav/+/v7/8vP2/9nd - 4P+5vMD/9/z///j4+P/PzM//g4SJ/0dHTf/i5er/9vr6//P4/P+4wtj/JzRV/wQVPv8XK03/mpqn/xod - LP9QY3v/MElc/wUHBP8BAwP/BAIH/wsEBv8FCQb/BgoG/wIFB/8EBwz/AQMK/wEEB/8GAwv/BAMG/wME - BP8CBQP/AQQC/wEFA/8CBAX/ERQW/wkJDf8ODhL/GhcS/xMSCf8HCQT/AQMC/wAAAf8YEg//Lysp/yUi - Iv8QDg3/EQ4M/xMREf8TERH/ExER/xIQEP8UEhL/TEhH/05KSf80MC//UU1M/0xIR/9EQD//PDg3/zk1 - NP84NDP/cW9u/9jV1/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADj3+D/aGRj/2plZP8PCwr/DQsL/woICP8RDw//GRcX/ycl - JP8fHR3/WFpd/+rw9//b5O3/2+Xq/9rk6//W4Of/2uTr/9vl7P/Z4+r/2ePq/9ji6f/W3+f/09zl/87X - 4P84PUL/f4CC/2hiY/9wa2z/5OPl//r6+v/w8PT/ZWhs/8/U2P+FiY7/PDs9/4+OkP/19vn/qaqv/+bm - 7f/8/Pn/+/38/+Lo6f/o8vv/fomi/0NMdv88SFP/2trQ/yItKv85PE3/Jh8u/1Neav+FnLD/i6fG/4Kf - yP9unsP/ZJS8/1uLtf9ThK7/TICm/0h4n/9Icpb/O1yA/zlTdP86UXD/JDJE/wgSH/8ECQ7/CgkI/wkH - Bv8AAgj/AwEE/w4ICv8aFRj/Gxkc/wYJD/8BAgX/CgsM/yIjJP8YFxn/EQ8P/woICP8JBwf/Dw0N/xMQ - EP9LR0b/RkJB/0lFRP9XU1L/TEhH/0hEQ/8+Ojn/PDg3/zo2Nf9IRkb/mZmZ/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACMior/ZmJh/0RAP/8ODAz/DQsL/wsJCf8XFRX/GRcX/x8cHf8oKS3/2+Ho/4mSm//g6vH/2ePq/9ji - 6f/X4ej/2OLp/9rk6//Y4un/2OLp/9jh6f/X4On/zdbf/2Zsc/+Iio7/c25w/6qlpv/39vj/+fj6/97d - 3v9XWlz/tLi8/yInKv/Mzs//+/v7/9/g4P/v8vX/ysrN//j39v/k4uD/5OHc/9nc2v/5/f3/vc/Y//T2 - +f9zfYj/lJCa/2l2ef8SHSr/NHOa/z2P0v89ktf/M5TQ/z2Nzv84icz/OIfL/zuLy/87isj/LYbL/zGD - yv83gcb/PH/H/zh7wf80gMP/P365/1GAtv84X47/JD1g/wELF/8BBQ//AwUI/wkEBf8IAgL/DgsH/ykm - If8eHR3/AgQF/wICAv8iICD/FhQU/wYEBP8RDw//EQ4O/xwYF/9KRkX/SERD/zMvLv9RTUz/SkZF/0VB - QP8/Ozr/Ozc2/zo3N/90dHT/6OTm/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnZGP/cGtq/xYUFP8ODAz/CwkJ/wsJ - Cv8ZFhf/HRsa/xYYGf/Y3uX/maKr/9vj7P/c5u3/2uTr/9nj6v/Z4+r/2+Xs/9fh6P/Z4+r/2uPr/9bf - 6P/U3eb/xM7V/zc8P/+EgoT/zcnK//j29v/z8/P/eXl5//X3+P9dYWL/0dTY/7y9wP/d3+D/+/z8//v7 - +//5+fn/3tzi//77///38vP/+/n5/wkICf96pdL/VZ7V/+L5/P/z+vj/V1p3/9bh6f8eIC7/CBYy/2SW - xv9Il9P/RY/X/zyI0/89jNX/QIvT/0GJ0f86iM//NobN/zSFzP8xhMv/L4LJ/zWAxP8zfsL/L37B/yx6 - vf8vfcL/OnvG/z+Ixv81dKD/FzlX/wgRJP8JDg//BQQC/wkGA/8aGBf/Hxwe/wkHB/8DAQH/FRMT/xoY - GP8aGBf/QT08/0VBQP9KRkX/R0NC/1dTUv9KRkX/RUFA/0E9PP8/Ozr/NjQ0/0ZGRv+enp7/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABkXl3/W1lY/wwKCf8JBwf/CwkJ/xMQEf8YFxP/ExUV/7a8w//Z4uv/2eDr/9nj - 6v/a5Ov/2OLp/9ji6f/a5Ov/2ePq/9nj6v/W4Oj/1+Dp/9bf6P/N2eH/Vlxh/3t7f//LyMv/6+vx/8G/ - v//t7e3/XF1d/9XX1//IzM3/yMvP/+zu7//8/v7/+vr6///+/P/5/fv//f79//r5+v/n5+f/FhkY/wwJ - CP8qRFr/SpLI/6XN8v/0+/b/cniD/7nCxP+Mh5P/Ehk5/zBci/9OmM3/PpHL/zuSzv88kM3/PY/K/zqL - zf86icz/OYfK/zmGyf84hcf/M4LI/zOBxf84gMX/OHvB/zp9wv8ue77/MXfA/zJ1wf8ver//L3q8/z1v - qP8UNFn/DRsq/wUGCP8GAwL/HRsb/xYUFP8MCgr/DAoK/xgWFv9LR0b/SkZF/0M/Pv9EQD//OTU0/1NP - Tv9JRUT/RkJB/0A8O/85Nzf/Ojo6/3Nzc/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHBwcP9iXl3/NTAv/wwK - Cf8KCwn/CQoI/xoVFv8dGhv/IyUm/+To7f/V4uf/1+Ho/9bg5//W4Of/2ePq/+Hr8v/L1d3/4Ory/9vk - 7f/Y4er/1+Dp/9bg6v+vuMD/OD9E/21scf+0sLL/zMvR//Ly8f/8/fj/ztDR/4qMlf/Dxcn/8vb0//X3 - 9v/5/P7/9/r///b5/v/4+/z//vn2//76+//0+vz/eXl//wYLA/8DDxX/UIGo/1Gc1v/T8v3/6ebn/0JW - T//U5en/WVpu/wwTIf9Tk8D/QZDY/0KO0/88j8f/PI3O/z2J0f86hc7/OYbL/zeHx/83hMr/NYLI/zaB - xv80f8T/NHzC/zZ8wv8ze8H/MXm//zN4vf8zd7z/Mnm3/y55uv87ebf/K1N8/wEAGP8FBA3/CgQK/xAR - Cf8ODQn/VE1R/0ZAQv9GQEH/RT4+/0U9Of9BOjr/VE9Q/1BLTP9IREP/Qj49/0E9PP82NDP/SkhH/6in - qP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA6ubo/2hkY/9uamn/CQUF/wwKCf8KCwn/EQ8P/xcUFP8fHiD/1Nrd/9jj - 5//X4ej/1d/m/9Pd5P/U3uX/r7jA/4+Yov/U3ub/2eLr/9jh6v/Z4ur/1t/n/9Xf5/+wusD/SlBW/xMS - Gv8GCAn/CAkM/wMDCP8kHx//Qzo2/6Ktu//q+f3/8f39//r79v/+/fL////5//X79//5+v3///j///38 - /P/7/fv/7fLv/zc1Nf8WFBj/GSAr/16Zy/9vr9H/6+36/8C7wP/q8fL/bXV9/x8iMv8tXHz/UZ7U/0CJ - 1P8+i9X/OIzN/ziNyP86iMj/O4TJ/zeFyP82g8j/N4LH/zWAxf80f8T/NX3D/zR8wv82fML/M3m//zJ4 - vv8zdb7/LXW//y13vf8zdrX/Onqz/0Bql/8GFCL/AAMM/15dYv9CPDf/Q0A8/0NBQP9FQ0P/ODc5/zQx - M/83MjP/UEtM/0xIR/9GQkH/Pzw7/1BOTf87OTj/fn5+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmpiX/2Zi - Yf9OTEv/DQkI/wwNC/8HBQX/FBIS/y0sLv8rMTT/3ejs/9fh6P/Z4+r/2ePq/9Pd5P/U3eb/yNDc/9Ha - 4//d5u//2OLp/9nk6P/Y4+f/2ubs/8za4P+3w8r/Vl5l/wcMDf8JBAT/GhMU/xgdKP9BWG7/dLrr/2+3 - 7v9preD/kr/p/9Lv//+QwOP/gLXc/8Tp/f/v+////f71//3//P/4/v3/9PT1/9HI1P8UHSf/HB4j/7a9 - uf9zgYf//ff9//D89f+KiY7/e4iK/767y/8YKkv/V5rD/z6Qzv9Ai9D/PYbQ/zmIzf81icr/OIbL/zaD - yP81gsf/NoHG/zR/xP80f8T/Nn3D/zV8wP80esD/NHrA/zJ0wv80d73/MXi5/yx0vP8ob7z/KnjA/zJ9 - uv8+TWf/TkBB/z8/O/9BPTj/REA7/1tWV/91dXv//v3+/0xHSP9bVlf/TUlI/0pGRf9EQUD/SEZF/zY0 - M/9QUFD/p6en/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmVj/3Bsa/8TDg3/CwoJ/wQEBP8NDQ3/YWBi/4OF - if/f6Oz/2ePq/9rk6//Z4+r/2OLp/9nj6v/X4On/1+Dp/9jh6v/X4Oj/pK22/8XP1v/S3+f/2OXt/9fi - 6v/Z4+z/BQoH/xAMBf8ECg7/cJa3/3C48/9zueX/Z7jq/2C17P9kuO7/YrHk/2Sw5P9YtOr/WrHo/2Kn - 3P96ven/vub6/+/3/v/5/PX/9P3y//z79v+Jko7/5Ozz//X+///w+/j//vX7//b8/P/l4uz/GyY2/1tm - aP+qqKf/K0lm/1CTy/87kNr/OInO/0WKyv85h8z/OIbL/zeEyf81gsf/NoHG/zWAxf80f8T/NHzC/zN7 - wf8ye7//Lnu+/zV5uP85eLj/N3W7/zV0vf8udrj/JXS+/zhytP8kOEz/Pz03/0E9Pf9DOjr/TEA+/8vE - yf/07vL/TklK/0E8Pf9QTEv/TUlI/0lGRf8wLi3/Pz08/zw8PP+CgoL/5+Pl/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADQzc7/aWFh/2diYf8TERD/CQkJ/wcHB/8LCgz/8/f6/+ry9v/j7fT/4Orx/9vl7P/a5Ov/2OLp/9jj - 5//Z4+n/2eLr/8fP2/9HT1z/QktZ/+n1+//a5u//3Obt/0VJTf8PCQX/CRUl/4rE6f90ve//b7ns/266 - 6/9tuOn/bLjo/2u36/9mser/ZrPr/12z6P9bsuj/YK3o/1qr6v9creH/W6LZ/3255v/C6Pz/7fn9//r5 - /P/9+vj/+/v5//D39//4+/f/tri8/7zHyP/t9/n/vb+//y4tMP8/PD7/P0lU/zlgfv9Ljcr/NIjW/zmK - zv85h8z/N4XK/zeFyf80gsX/NIHG/zWAxf8zfsP/NHzC/zN8wP8xfL7/MXnB/y93wP8veLz/L3m4/zF2 - uf80crr/J3S2/zl8uP87YYr/LDhC/zk9Pf9BPjr/QDs7/1RQUP9HQkP/R0JD/1hTUv9RTUz/SUZF/zY0 - M/9BPz7/Ozs7/1NTU/+7urr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/fH3/aGJj/zgyM/8MCgr/BwcH/wcH - B/8ICgv/dXh8//D2+//s7/b/5ezx/+Pq7v/e5+v/2uXs/9rl7f/X4en/2uPs/9Hb4v/h5+z/1uPz/9zh - 6P+pubL/DgQK/yYxT/+IyOz/cr/x/3a78P9svO7/b7ru/2257f9suOz/aLbr/2W17P9js+z/YrTr/1+w - 6P9er+j/Xa7n/1qu5f9XquP/V6jj/1Wm3/9ZpNn/jMLi/7HZ8v/R6vv/8Pf9//X4/v+ssa3/n6qx/+71 - +//3+fr/8O7p/9bX2v85Pzv/3Nnc/yU+Xv9Jj8b/OI/G/0CI0P86hcz/NofH/zWFyP8vgcr/L4LG/zF/ - xv8zfMb/NXvG/zR8wv8yesD/Mnm//zJ4vf8yeb3/MXa8/zB1u/8wdbr/LnO5/ypwu/86dKr/LT9P/z8+ - Pf8/PDv/Qjw6/0Q8Pv9EPz7/Qzoy/1NQSf9GRkb/NTMz/z44Of9AOzv/REJC/4SEhP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABnYmP/RD4//xINDv8LCQn/CwsL/wUFB/8HCQr/BwcH/1NTVv/6/P3/7vH4/+jt - 9P/g5/D/3+bv/97m7v/c5Ov/2uTr/9nl6f/j5vD/4ezv/wcHC/8XLkD/i8rs/3HG7f9wvu//e7rw/3C8 - 7f9vuu7/brnt/2y47f9suO3/aLbr/2Wz6/9ktOv/YbLq/1+w6f9druf/W67m/1qt5f9crOf/Vafh/1Wl - 5P9Nn+f/UqPl/1Gh3f9QoNb/WqTY/7jj/f/7/P7//vnt/5ebnv9NXG7/1+Ho//D4+//49fX/j42S/yc6 - V/9kmNz/MIjL/zqKyP9Chcv/NoPP/z2Cx/88gcb/OYDE/zOAwv8ugMH/M3vB/zJ6wP80esD/Mni+/zF3 - vf8xdrv/MXa7/zB1uv8vdLr/MHO2/y10uv8wcLj/M09w/z4+O/88PDP/PD88/z4+Pv87Nzn/YFhZ/09K - TP+enJz/EQwN/0ZBQv86ODj/VVVV/7Oysv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGenv9YU1T/EA4N/w8N - Df8dGxv/CgoL/wgICP8RDAv/FBIS/z8+QP9zc3v/sbW9/+/1+v/p7vP/4+ju/+Dn7v/h6PD/3ubv/+j1 - 9/8BAQb/Ii4//4HC5P91xvH/c8Ly/3u98v99uvD/b7zt/3C87f9vuu7/bbjs/2u37P9qtuv/Z7Xq/2W0 - 6f9js+r/YLLp/1+w6f9brub/XK/n/1ep4v9ZrOT/VKfi/1qk3/9Zo+D/T5/b/1Oi4v9Pndv/UJzh/0qZ - 0v+Yyev/7fr///r59P/0+v3/bXeJ/0lVXf/y+Pz/sLjB/zU9Rv9YlcT/MovN/zOIyv83iMr/NIbK/zmB - yv87gcf/N4HF/zKBxP8yfcL/M3vB/zF5v/8zeb//M3m//zF3vf8wdrz/L3W7/y91u/8tdLj/L3W5/ylv - uP8rbbn/QmiM/y81OP8/Ozb/RT06/0E+QP85Nzf/T0xI/5iWlv+UkpP/NjI0/z49Pf88PTz/i4uL/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoaP9TT07/JyMi/ygkI/8TERH/CQkJ/wcHA/8MCwn/DAsM/35+ - gv+4t7z/ICIj/46Sk//p7fH/6u7z/+nv9//o6PH/M0A//yUsPf+YzvD/esXz/3/B8f9/vvD/gL/x/3m+ - 8P9xv+7/c7zu/2+77P9vuu3/brnt/2u36/9ptuv/Z7Xq/2az6v9js+r/YbLp/12w6P9cr+f/Wqzm/1mr - 5f9YquT/U6jh/1Om4f9So+P/UqHj/1Oe4/9Podj/SZ3c/1Oc3/9Hks//Vavc/0yUyP9tp9z/v+j6/73O - 1f/o6u7/1Nnf/6efuv8zR23/S4K5/0WI0f82h8f/MoTM/zWBzf82f8r/N4DH/zR/xP8yfcL/MnrA/zF5 - v/8yeL7/Mni+/zF3vf8xd73/L3W7/zB1uf8tdrf/LHO9/zZzuP80dLj/NGWf/ywyQP9IOzb/Pzw4/zU5 - M/9bXFP/fHp5/6mqrf8QERX/REND/zw7Ov9aWlr/s7Oz/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NHT/2Je - Xf9lYWD/JSEg/xcVFf8ODAz/BAgH/wMHBv8DBQX/CwkJ/w0JCv8fHRz/IiMi/w0PEf9SVlr/2dzh/5GX - mv8HBgj/msbf/3K+7v96v+3/eMPw/3zD8P91we7/c7/v/3m87/9zve3/c7zu/2+77P9vu+z/brnt/225 - 7f9oter/aLbr/2a06f9js+r/XrHp/12w6P9bref/Wqzm/1ms5P9YqOL/Vqfh/1Sl4P9SpOD/TqLe/0+f - 3v9Nntz/Sp7a/0iY2f9Nmdz/Q5bZ/0qV2v9Jl9X/R5bN/1SX0/9yrNn/nMnm/+Hu+P+Vnaj/Fi5G/09+ - tP9AhsP/MIXH/zKDxv84gsT/M4DF/zR/xP8yfcL/M3vB/zF5v/8xeb//L3e9/y93vf8udrz/LnW6/y52 - uv8udbn/KnK6/y1yuP8qdLv/Omua/zU1Ov9IQEL/RD9E/0Q/O/9paWj/fH+D/2ttcf8/Pz7/QkI//0FB - Qf+UlJT/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAe3h4/2FcXP9mYV7/DQkI/woICf8HBwf/BgYG/wYG - Bv8JBwf/FRMT/zs3Nv8yLi3/DAoJ/w0LCv88Ozv/UEU9/4GUqf+Dxez/ecjw/4bE8f9/wPf/gr/z/37A - 8P97wPD/c7/v/3e+8P9zvO7/crvu/3C77/9vuu7/bLjt/2u37P9otez/ZrPr/2Wy6v9js+r/X7Dp/16v - 6P9bref/Wavl/1uq4/9WqeH/UKfg/1Gk4f9SoeD/UJ7j/0+e4f9Ond7/Tpzd/0ya1/9Mmdf/SJbY/0WU - 1/9Ckdr/QZDZ/z6P0v85jtL/SI3D/4Cmw//K2+n/rbvT/zltof81hc3/M4TL/zaDxf80gcb/M4DF/zR/ - w/8ze8H/NHzC/zV7wf8yeb//Mni+/y91u/8yeL7/MHa7/zB1u/8vdLr/L3S6/zJztf8sccD/KGKV/0A6 - Ov8/QDz/NjEy/1lWWP+ysrj/qaqu/xUQEP9KR0X/REJB/2FfXv/Ix8f/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAZWBg/19aV/87Nzb/DAoK/wcHB/8GBgb/BgYG/woICP8nJSX/R0NC/zo2Nf8QDg3/FBIR/yUm - JP8OHCX/i8zp/3rE8f+BxfT/fsX3/3LK7/91yO7/d8Xu/3fC8f92v/P/d77w/3S97/9yu+//crvv/2+6 - 7v9uuu7/bbnu/2m37P9nter/ZrPr/2Oz6v9hsun/Xq/o/1yu6P9bref/V6rn/1io4/9Yp+D/V6bf/1am - 3f9Wo9z/UaLb/06g2v9Kn9n/RZ7X/0WZ2v9FmNb/R5XU/0eVz/9GlM3/Q5HU/zuO2f8zhNP/QYzV/0qP - z/9Ojbv/Yqzo/ziJzf83hMr/OoDG/zWCx/8zgMX/NYDF/zR/xP81fcP/M3vB/zJ6wP8zeb//Mni+/zJ4 - vv8xd73/MHa8/zB1u/8uc7n/L3O6/y93t/84b7P/MF2D/z0yMv9DQkH/SUVD/6Ggov+en6P/aWlt/0E/ - P/9HRUT/TkxL/5CQkP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrp6j/YFxa/2hjZP8NCwv/BwcH/wUF - Bf8HBwf/DgwM/0hGRv90cG//JyMi/xsZGf8ZGBj/GRYW/5yxx/+Eyev/g8jx/5nI9f96xvX/iMH1/4bA - 8v+CwfL/fMHw/3nB7/94wPD/dL7u/3O87v9yu+3/cLvu/2667v9tuOz/arfr/2m36/9ntOv/ZbXr/2Oz - 6f9gsen/Xa/o/1yt5v9cruT/W6vm/1el6P9PpOX/S6bi/0mj4f9LoOH/UZ/h/1Cd4f9SnN7/Up7f/0yb - 3v9HmN3/QpXc/0GS2v9ElNT/QpPS/0CP0P8/j9L/OIvN/zuP1f86i9D/O4bK/zqGyv84hsv/NoPI/zWC - x/8zgMX/NIDF/zN+wv8yfcL/MnrA/zJ5v/8zeb//Mni+/zB3vf8vdbv/LnS6/y90uf8udbv/LnS0/y1x - uf8ucb3/L0Vh/0A9Of8xLSr/W1lZ/6qrr/+qrbL/Ly4w/0pIR/9BPz//ZGRk/8/Nzv8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABoZGb/YFtc/0lFRP8GBgb/BQUF/wcHB/83NTX/V1VV/19bWv81MTD/FhQT/xcV - FP8PEA7/JTRC/1R7jv9XfZD/X3+V/5PS7f91xPD/d8bz/3nF9P9+w/P/fb7q/3nB8f91v+//dL3v/3O8 - 7v9xve7/brrr/2657f9suOz/bLjt/2q26/9otuv/ZbTp/2Oz6v9fsen/X7Dn/2Gv5P9ZquT/Wanm/1+o - 5f9nq+T/UZG7/4W73f+94fL/1u35/3eHj/8QHyD/FSg1/4GrzP84bpv/XJ3T/1Ge4P9Ck9f/PZHV/zuS - 0v87kNH/QIrW/0KK0f9Aic3/OYjM/zSIzP84hcr/NoPI/zaDyP81gsf/NYHG/zN+w/8xfcL/M3vB/zN7 - wf8zesD/L3e9/y93vf8vdbv/L3W7/y11t/8vcrz/KHa6/zZ0w/84frj/MTlG/0BAQP9PTkv/pqio/6Gl - qP9DQkT/RkRD/0pIR/9DQ0P/mZmZ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcV1j/YV1c/xwc - HP8LCwv/FxcX/4eFhf9/fX3/d3Ny/25qaf9kYmH/NjMz/xkXFv8JEgz/BwcH/w4LB/8GCwr/EBMe/ztS - YP9zmLL/jcPn/4fJ9/99xff/ecHx/3bB7/91v+//dL7u/3G97v9yu+3/cLzt/2667/9suOz/bLjs/2e1 - 6v9nter/Y7Lr/2Oz6v9gr+j/Xa3r/1es5P9qs9r/k73W/z1JV/8oKy7/T1Nb/32Fjv93hY3/MD5I/xUY - Hf8WFRz/SkxP/wQEB/8CAgL/BRAW/0Boj/9SlNH/QZDU/ziOzv8+kM7/PYzQ/zyKz/84ic3/OYnM/zeG - y/83hcr/NYPI/zeEyf80gcb/Mn/E/zN+w/8yfcL/MnrA/zJ6wP8xeb//MHi+/zF3vf8wdrz/L3a8/yt2 - t/8wdLr/JHS2/zJyt/84ZY7/ODs7/yonJ/9naGf/rrGy/0lISf8+PDv/UlBP/05OTv9qamr/4N3f/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHp6ev9gW1z/WVVU/wsKCf94e3n/oKGf/4OAf/9jY2P/c2hk/2Bh - Xv91b3D/VEtJ/11ZVP9EQz7/KCgn/xYWFv8MCw7/AwQA/wkKBf8JDAv/EBch/y46S/9hkbH/ls3w/4zM - 9P93ven/b7vs/2y78P9st+v/cLz1/2i17v9zuOv/bLXs/2S16/9tuuz/Zb/e/2ur8/9psej/rt/5//7+ - /v/z7/T/Mj86/xcaIP/Z6/f/zeHt/7XI4/+Wr8v/e5O0/3mIlv/FzNj/AQIM/wQCC/8JBgH/BwgA/wII - E/9ThKb/OIzU/z2R0/87lcz/PozP/zyJz/87icz/OYbL/zmGy/83hMn/OIXK/zaDyP80gcb/NIDF/zR/ - xP8yfMT/MnvD/zB6wv8yesL/MHjA/zB1vv8xdr7/MHe7/y91u/8wdrz/L3S5/yl1w/8/REH/QD9B/0xO - Vf+wrrD/RkhL/0ZCQf9QTk3/TkxM/0pISP+ioqL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF1Z - Wv9gW1r/NzMy/4F/fv+GgoH/DAgH/y0vL/9zZ2X/b3Br/21kZP9lYmL/XV1X/1lYVP9APjr/QT84/1BO - Rv9GSEz/NTY5/yUkJ/8MCw7/BAMK/wsHB/8DBAj/AQEH/xIiLv9ab4H/ha3V/4XJ6/+Cw+//e7vw/2fA - 7P9ruev/Yrbq/3y28f9itfP/bbno/0Bdcv/l5fD/+fzx/9zz/P+LrOD/V43N/0mMxf9PjdP/T4jb/0+T - yP9Sjcj/S5LW/1Ga4f9fmtT/Snel/wwgR/8DAAv/EQQJ/wgGCP8aMUD/WJ3S/z2O1f9CitX/P4zP/zWN - zf87iM3/OYfM/ziGy/83hcr/NILH/zWCx/80gcb/NYDF/zR+xv8zfcX/M33F/zB6wv8yesL/MXnB/zJ4 - wP8xeL7/L3W7/y52vP8vdrz/L3W6/z9sn/84OT7/ODIw/3p3eP89Pj7/U09O/1NRUP9TUVH/VlRU/3Nz - c//r5+n/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv7u8/15ZWP9hXFv/QDw7/2xnZv+Cfn3/eHl5/5eO - kP+Kh4P/aGNi/2J1f/9qgpX/YXeK/191hP9KXm3/PlFe/0RIUP9AQ0b/PDw8/0I+PP9RSEP/SEQ9/zUv - Lf8jHh7/EhAS/w0LEf8OCgv/BwcM/y1Sb/9wtuX/bsDx/2q47P9tt+z/bLXq/2ay6v8WKTT/gH6I/+Px - +/90ocX/Q3/H/0aEy/9Bic3/PofU/0GK0v9Gh9b/R47U/0OM2f9Bjt7/RpDX/0qV2/9Kk9z/T5Xc/2Cl - 4v8fQ1j/AQUL/wYEBf8NHy7/U5TM/zmO0v8+jdD/P4vS/z2Kz/86ic7/OIbL/ziGy/83hcr/N4TJ/zaD - yP80gcb/NX/H/zR+xv8yfMT/MHzE/zF6wv8yesL/MXnA/zF5v/8weL7/MHe9/zB3vf8tdbr/J3HB/zhA - Rf9LRkL/WVRO/1lYV/9XU1L/WFZV/1VTU/9VU1P/SUlJ/5+fn/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAbGlo/2FcW/9KRUX/KCQj/3RxcP+Njor/hn+E/ygjIv9gYGP/pNDs/5DL9v+OyvT/jsjz/5HJ - 9P+PyPH/jMrw/4vM8P+Ixuv/e7XW/2meu/9dg57/SGh5/0RZZP9ATEf/Q0tB/zY+Pf8zKjL/XIWg/2m7 - 6v98vPb/bLjt/3W17f9bueL/RHeU/yshI/+Vp8f/PobN/zmF1f9GhNj/O4fN/2Sbz/8NFTj/UY29/0OJ - xf+KoLT/WX+l/0iM1/9OkNb/bJzM/w8uWv9smN7/S5bf/1GY1/9fkdX/Bwcc/wkCAf8gO07/SJTK/zuO - 1/9EidP/PIzQ/zqLz/85is7/OInN/zeIzP85h8z/NYPI/zaDyP81gcn/M3/H/zN/x/8zf8f/NH7G/zJ8 - xP8wesH/L3q//y96v/8ueb3/L3q+/y15vv8qdr7/Plt4/zo+Pv82Min/Y2Fg/15aWf9cWln/VVNT/1tZ - Wf9aWlr/d3d3/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADl4eP/XVlY/2FcW/9QTEv/Kywq/zUz - Mf9qYmz/DgsM/210fP+MzPT/is3z/4jK8v+HyvT/hcnz/4TI9P+Fye//hMny/4HH9f+FyfP/hsPt/3/E - 7/99wu//gcXy/33B7/99xPL/js30/4nA4/99vuf/cLzw/3O87/9sven/brju/2/C8v8OGjD/YpW4/zeE - yv8/fM3/OoLF/0OFxv+l0e3/+ff7/5uaoP9Jc5j/TYnU/1CMvf9VlNP/RpDb/7ni/P/z+/z/YmRg/0x3 - m/9UlNv/V5jb/0Sb6f9lptX/ABIl/wkDCP9slMf/O5Lc/0KQzP89jtL/PI3R/zqLzv85is3/N4jL/zeH - y/83hcr/OIXK/zaCyv81gcn/NIDI/zF9xf8zfcX/MnzE/zJ8w/8xfMH/MHvA/y96v/8ver//Lni6/yt3 - w/9Cfr//Pj46/z0/QP9XU1D/Yl5d/2JgX/9cWlr/W1lZ/1dXV/9FRUX/sbCw/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACPjY3/XFpa/1xYV/9aVVT/VFVR/1ZQUf89OjT/jqzC/4/O9f+MzPX/isrz/4rK - 8/+KyvP/icny/4nJ8v+HyfL/hMjz/4TI8/+CxvH/gsXy/4HE8v9+w/L/fMLx/3vA8f94wPD/d7/v/3e/ - 7/91vO7/db3v/3C67v9tt+3/bKzL/0lqlv86gMv/PYHN/z6CyP9Igtf/QofQ/7Pc+P+vr7n/7+7m/3OE - lv+nu+T/4u3//5Gmv/8+Woj/3uz6/4iLiv/38/n/Z5fK/1iS2/9XoNn/Tprd/1qa4P9fnuz/ARQq/1ln - fv9Akdf/PYzV/z6P0/89jtL/PI3R/zqLz/85is7/OYrO/zeIzP82h8v/NYbK/zaEyf82g8j/M4DF/zJ/ - xP8yf8T/MX3D/zF6xP8wecP/MXrE/zB5w/8tdsP/LHe7/y18xf80OEf/SD08/zEvLP9qZmX/ZGBf/15a - Wf9YVFP/Xlxb/19dXP98enn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcWlr/XVlY/1tW - Vf9VU1P/WVNU/zY1Mf+kxt3/isr2/43N9v+MzPX/jMz1/4vL9P+KyvP/isrz/4jK8/+HyPT/hsfz/4PG - 8/+AxPH/gMTx/37D8v98wvH/e8Hw/3nB8f93v+//dr7u/3a97/91vO7/cb7t/2+77/90qdX/T47A/zyB - z/88gMr/U4nI/2KAk/87TGn/O4fJ/4+5zP/39Pz/zb/Z/9XY5P/g3+f/08DY/7Wtxv/Y0ev/kpSo/4+m - uv9Ymt7/d5nB/26FqP9LnuH/V5fj/1ib4f9kmcj/Qk9g/0mS0f9Gktf/P5DU/z6P0/89jtL/O4zQ/zqL - z/85is7/OInN/zeIzP82h8v/NobL/zWDyP80gsf/NILH/zB+w/8xfcT/M3zG/zJ7xf8xesT/MHnD/y53 - xP8ueb7/MH7L/zE6Sf9GPz7/R0RB/2RgX/9lYWD/ZGBf/2BcW/9kYWD/WVdW/01LSv+8urv/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAALm4uf9eWln/XFhX/1ZTU/9aUlX/OTg1/5q71f+JyvT/jMz1/4zM - 9f+NzPX/isrz/4nJ8v+JyfL/h8ny/4fI9P+HyfT/hcj1/4HG8f+AxfD/gMby/37F8v99w/L/e8Py/3nB - 8P93v+//dr7u/3e97v9zvez/cb3v/0t+s/8zhMH/N3rL/ziAzP8zgNL/PW6s/3Sdzf8/dKj/xrrc/82y - 3//47fv/9/v3/+Hl7f+BjI//5+no/97O4v+slrj/tqrJ/1uApP9XkND/dZ/Q/1+i4f9SmuD/XZzh/1Of - 5/9DW3b/VJnS/0uV2f9Bktb/QJHV/z6P0/89jtL/PI3R/zuM0P85is7/OInN/ziJzf83h8z/N4XK/zeF - yv80gsf/M4HG/zOAx/8yfcf/MHvF/zB7xf8we8X/LXrE/zF7vv8se8j/IDBB/z88PP9APTr/ODQz/2xo - Z/9saGf/Z2Ni/1VSUf9eXFv/aWdm/39/f/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGln - Zv9bWVj/VlVR/1lTVP9CPzn/hqS6/4/N9v+Pzfb/jMz1/43N9v+MzPX/i8v0/4vL9P+IyvP/iMn1/4jJ - 9v+Ex/T/g8jz/4HG8f9/xfH/f8by/37F8f96wvH/ecHw/3e/7/94wPD/eL/v/3a/7/90vO7/TY/K/zN/ - w/87fsr/OXzB/6PJ5/9PXoD/EzFX/7rL3v+cerH/7vD7/+j5/f+PkKL/5+Ho/3R3e/8OCg3/8fX7/9jX - 6//Kut//trKu/1ai7/96rt3/FC5R/2yh0v9aneP/T53k/1SGuv9Vm9L/R5PY/0OU2P9Bktb/QJHV/z6P - 0/8+j9P/PI3R/zqLz/86i8//OInN/zeIzP83iMz/NYbK/zSFyf8zhMj/M4LI/zR/yf8yfcf/MXzG/zB7 - xf8ue8T/M3y+/yp5yP8bMUX/PT4+/0RAPv9FQUD/c29u/0E9PP9saGf/TUpJ/2tpaP9wbm3/SkpK/7Kx - sv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1tPU/1VTUv9VWFL/WVVQ/0pHPv9IYHP/lcvx/43L - 9P+Ly/T/jMz1/4vL9P+OzPX/isrz/4fJ8v+HyPT/h8j0/4XI9f+DyPP/g8jz/4DH8f9/xvL/f8by/3vE - 8P96wvH/eMDw/3jA8P91v+//eMDv/3W97f86kMz/RH/H/zl/w/9ckMz/8PX7/+ru7f+Kh5v/ztTs/6pz - tv/99Pz/7vH1/83U2P+uubn/eHV//7Wtvv/Q29f/7vD4/8Sm2f/9+/3/mMPa///89v+gpKb/VV97/1KX - 5v9god3/SZbl/1CazP9Kl9z/RJXZ/0KT1/9Bktb/QJHV/z6P0/89jtL/O4zQ/zqLz/85is7/OYrO/zeI - y/83iMv/NYbJ/zSFyP8zg8j/NYLL/zJ/yP8yf8j/MX7H/yx8xP80fb//K3vK/xcwRf89PT7/Qz48/0RA - P/86NjX/DQkI/4B8e/97eHf/bGpp/4iGhf9wcHD/h4eH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAiIiI/1xaWf9cWFX/SkpC/x0iK/+T0vL/k8v2/47K9P+JzvX/i830/4/L9f+Ny/T/i8v0/4rK - 8/+JyfL/icny/4XJ9P+EyPP/gsXy/4LF8v+BxfL/gcT1/37B8v98wfL/e8Dx/3q/8P90vu//dL/v/1Gc - 1P85gMD/OHvG/1OIwv/H3Ob/1Nzh/7HL5f+53fn/Zitp/9Wz9v/f9O3/7uXp/3t6hP9vcXT/4+/s/+3u - 8v/j3/P/yqrk//v4/P+TyfH/kJyq/+Lf4P92nL//VZzg/1me4f9Ul9z/TZjb/0WY1/9Hltn/RZXY/0KT - 1v8+kdX/PpHV/z6P0/88jdH/O4zQ/zqLz/86i8//OYnQ/zeHzv81hcz/NITL/zSDy/80gcr/NIHK/zJ/ - yP8xfsf/Mn3G/yqBv/8ygsb/FCVE/0lBOP9BPkD/Q0FA/x8fHf8ICgj/XV9d/4mIh/9KSEj/1NTU/5GQ - kv9dX2D/2dfZ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXFpZ/1tTU/9XU0//CwwR/57N - 6f+Jy/n/jMz3/47L9v+OzPT/i830/4zM9f+MzPX/i8v0/4nJ8v+JyfL/h8j0/4XI8/+Dx/P/gcXy/4LF - 8v+BxfT/f8Py/37D8v98wvH/e8Hw/3bA8P92wPD/dcD2/zV7vf84e8r/MXnG/zl4wP9LisD/QHmy/0N9 - zv+xqtH/ijWD/8mj6P/e3/v/7vXw/+/u8P/v7Pr/4Nzx/8vS2v/k6P7/mbXV/0qU2/9jmtb/ZZzc/06e - 4P9YnuT/W57k/1Ka3f9Mmtz/Qpnb/0iX2v9Gltn/RZbZ/0GU2P8+kdX/P5DU/z6P0/88jdH/O4zQ/zqL - z/85idD/OIjP/zeHzv82hs3/NoXN/zaDzP80gcr/NIHK/zOAyf8zf83/MIHA/zmP3v8rLzj/PTw7/0I/ - Pv9APj3/Dw0M/w4MC/8LCQj/npyc/6impv+GhYf/qKep/0xOT/+bm5v/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADOy8v/Ylha/1xXVP8gHyH/bYWX/4bK8v+Rzvv/k8z6/47M9f+JzvP/jMz1/4vL - 9P+Ly/T/isrz/4nJ8v+HyfL/hsjy/4bH8/+Dx/P/gsbx/4HF9P+AxPP/fsTz/3zC8f97wfD/eMDw/3a/ - 7/91vfL/P4XF/zh8x/82fsD/O4LA/x9OlP9+foX/QoS//0+Lz//L0u//lmOn/6t0vf+qiMr/uZbY/8Sp - 1P/x6vv//vj+/6qyz/9Sktb/Kl2N/3uCkf9fmMn/XJva/1aa3/9XnOD/T5rd/0qc3P9Gm9r/Spnc/0iY - 2/9Eldn/QpPX/z+S1v9Bktb/P5DU/z2O0v89jtL/PI3R/zuL0v85idD/N4fO/zeHzv81hcz/NYTN/zSD - zP8ygcr/MoHK/y+Azv83fcT/Po3b/0pDO/84PUD/QT85/z07Ov8wLi3/GRcW/yMhIP+Jh4f/qqep/3Bv - cv+2tbj/pKWp/3h5ef8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoYWT/V1VT/z45 - N/8DBhD/otj3/5nR+P+KyvP/jMz1/47M9P+MzPX/jMz1/4zM9f+Ly/T/isrz/4rK8/+Ky/L/h8n0/4TI - 8/+EyPP/gsXy/4LF8v9/xfH/fcTw/3zD7/96wvL/ecHw/3S+7P91vPX/NHi5/zt7vv81eMf/KXe//y53 - vv9Aesr/tOD5/7bN2P8eIDX/sMjt/9jl///m8///0+z7/5XG3P+zwt//Q16I/xgtTP9Gjef/PYzf/1SW - 4/9Omd3/VZve/1Gc3v9Pnd//TJ7c/0ib2f9Kmdz/SJfa/0WW2v9Dltr/QpXZ/0OU2P8/kNT/QJHV/z6P - 0/88jdH/O4vS/zmJ0P85idD/N4fO/zaGzf81hM3/NIPM/zSDzP8ygcr/LoHK/zR8xv8UTID/Vk9D/0A7 - Qv9EQT3/RkJB/0A8O/9KRkX/T0tK/4yIiv+sqav/sbC0/5CPk//Lys3/S0tM/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTVFL/V1ZP/w8NDv9ihp3/lMvp/4bM8v+JzPX/k8v0/47M - 9f+MzPX/jMz1/4vL9P+KyvP/icrx/4nK8f+GyPH/hsjx/4TI8/+BxfL/gMTx/3/F8f9/xvL/fcPy/3zB - 8v94wO//d8Ds/3O97f9vt+7/M3jE/zx/wf86fMb/O33K/0KDvv/r8/7/4NHk/6Wwsf9Bh8L/QIDB/0d3 - of9cicv/Z57W/+3v8//m8Oj/V1dX/0WN2P9Ek9v/Up3T/0yR3v9Pm93/UJ7g/1Cf3v9Pnt3/TZzb/0yb - 3v9Kmt3/Rpfb/0WW2v9Eldn/Q5TY/0GS1v9AkdX/P5DU/z6P0/89jdT/O4vS/zqK0f85idD/NofO/zWH - z/8xhM//MoTM/zKEzP8xg8f/PIDM/wAKKP9CQz3/RjxA/0ZBQf9EQD//REA//zMvLv9QTEv/j4yN/7Gu - sP+urbH/kZCU/9TS1v+ura3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJWT - lP9aV1f/KyYn/wsGBv+q2vr/isr2/4vO8f+Xy/T/jsz0/47M9f+OzPT/jsz1/43L9P+Ky/L/icny/4fI - 8f+Gx/P/hsfz/4PH8v+BxvH/gcXx/4DE8f9+xfH/f8Lv/3zD7/96wO//d7/u/3a+7v92vvT/M3m0/z6C - xf84ecP/PXrD/8bg/P/J1Nr/nb7h/0KByP87fcX/ZnuU/1yCrv9BhcT/1N7u/8ba5/+budj/UZTZ/0uP - 2f9Tltj/SJXd/1Kh4P9Sod//UKDh/0+f4P9Ont//TJzd/0ua3f9JmNv/SJbb/0eV2v9DlNf/QpPW/0GS - 1v9AkdX/P5DU/z6P0v88jdH/OovP/zqK0f86iND/N4fR/zKE0v82hcz/NIfN/ymC0/9Eib7/MzQ7/0E9 - Pv87Qj//R0A9/0VBQP9HQ0L/REA//0hEQ/9XVVf/s7K2/7i2vP+ysLX/h4aI/8rIzP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhWVv9QTk7/BAsK/ztIVP+Jyuv/i8n7/47N - 9f+OzPT/jsz1/47M9P+OzPX/jcv0/4rL8v+KyvP/iMny/4fI9P+Gx/P/hcn0/4TI8/+AxPH/gMTx/4DE - 8f+BxPH/fMPv/3vB8P95wfD/eMDw/3S98P92vvT/WZ/a/zR5uv82er7/Nnu9/0d/tv9Bf77/OYHL/0CC - x/9Lhsf/QIfN/zWC2P9RjcP/UI3M/0yM0/9CkuL/SZDV/1ec2f9Xpuj/VKTh/1Sj4f9RoeD/UKDh/0+f - 4P9Nnd7/S5vc/0ua3f9Kmdz/SZjb/0WW2f9Eldj/Q5TY/0GS1v9AkdX/Po/S/z2O0v88jdH/O4vS/ziK - 0f83is3/OojL/zyHzP87g83/OobL/xMxWP9QS0//QUA9/0Q/Pv9HREL/SUVE/0hEQ/9HQ0L/SERD/0A/ - P/+vrrD/s7K2/7WzuP+GhYf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAtLKy/11aWv8sJin/Dw0K/3uWq/+IyPn/isjx/47M9P+My/T/jsz0/43L8/+Ny/T/jM30/4rK - 8/+JyvP/h8j0/4fI9P+IyfX/hsr1/4PH8/+BxPH/gcXy/4DD8P98w+//e8Hw/3rC8f93v+//dsHv/3S+ - 7v9zu/D/d771/2Kp4/8+hsf/NXzA/zF8yf84fsr/QYHH/0B/zP9ChM7/SYDP/0KJzv9IhtP/Q47X/1Se - 5P9iqub/Xark/1Ko5f9UpOH/U6Pg/1Kj4f9Pn97/UKDf/0+f3v9Ond//TJzd/0qZ3P9JmNv/RZbZ/0SV - 2P9DlNj/QpPX/0GS1v8/kNP/P5DU/zyN0f88jNP/O4rT/z2I0v87ic//NYnU/zOH0P9CgK//GRkr/0I9 - PP9FQ0D/TkRG/xoaGf8ZFRT/IBwb/yklJP9HQ0L/RUJB/1NRUf+3tLn/trO4/4mGif8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYmJi/1xYV/8JDQf/CwoR/5vE - 3f+Ry+//jcv0/43L9P+OzPX/jsz1/47M9P+LzPP/i8v0/4nK8/+IyfX/iMn1/4fI9P+Gx/P/g8bz/4LF - 8v+CxfL/gsXy/37F8f98wvH/esLx/3jA8P91wO7/db/v/3O97f91vu//crvt/3i46/90u/T/abLw/2Kp - 6P9YoN//UqTc/1Sk2/9ap9z/Wq7r/1+v6v9ksOX/Y6/k/1yq4v9YqeX/WKnm/1en4v9WpuP/UqPg/1Ch - 3/9QoN//T5/e/02d3f9Nnd7/TJzd/0qa2/9Gl9r/RZbZ/0SV2f9Eldn/QpPX/0GS1f8+j9P/PY7S/z2N - 1P87i9T/P4jT/ziI0/8uhNj/SJDN/wYjNv9UUlX/SkE+/0E/PP8fHBv/FBER/yEdHP8mIiH/NjIx/y8r - Kv9DQT7/Pz08/767vf+4tLn/i4eM/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAVVlQ/z04Of8PDAn/BgkN/6DU8/+Ly/T/j831/47L8/+MzPP/jcv0/4vM - 8/+MzPX/iMrz/4jJ9f+IyfX/iMn1/4fI9P+Ex/P/hMf0/4LF8v+BxPH/fsXx/37E8/95wfD/ecHx/3bA - 8P92wPD/dsDw/3S+7v9zve3/cL7y/2e58P9vuu7/brvq/2q77P9tt+v/abPt/2ax6v9nre//X7Ln/1qu - 6P9br+f/Vars/1mr5f9gq+H/Vqbh/1Wl4P9UpeL/U6Th/1Gi3/9QoN//T5/e/0+f4P9MnN3/TJzd/0iZ - 3P9Gl9r/RZba/0SV2f9DlNj/QpPW/0CR1f8+jtX/Po7V/zqN1P87j8z/N4rR/zuH1f87YIX/Kygl/0BE - Pf9JP0L/RUNB/wQMCf8bFBX/JyMi/yomJf8jHx7/CQUE/05KR/9HRED/Z2Jk/7u1uv+Qio//AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fn7/WFRT/yok - If8FBAP/DAsQ/5bQ8f+VzvP/jszz/4zL9P+NzPX/jsz0/47M9P+MzPT/isrz/4jK8/+HyvH/h8ny/4XK - 8v+EyPP/gsfy/4HF8v+BxfT/fsTz/33D8v98wfL/ecHx/3e/7/93v+//dr3v/3a97/9xvO//cLvv/2+7 - 7/9suOz/bbnu/2u37P9qtez/ZrPr/2ey7P9kser/YbDp/1+u5/9bq+f/W6vo/1mp5P9YqOP/V6fi/1Sk - 3/9VpeL/VKTh/1Cg3/9RoeL/T5/g/02d3/9Mm97/SZrd/0eY2/9HmNv/RZXb/0SU1/9ClNX/PJLY/0GP - 2f8/jtX/O4/T/z2Mz/83jNH/O3Ke/wkJEv9VUE//REA//0M/Pv8aGBj/DgwM/w8NDf8XFRX/Liws/xoY - GP8LCwv/Kygp/0RCQv8+PDz/wb6//4qGi/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYU1P/W1VV/xYTE/8EBQj/CgYN/6TM5v+JyPf/jsn6/5LM - 9P+Ny/P/jsz0/4vL8/+Ly/T/iMrz/4fK8f+HyfL/hsry/4TI8/+EyPP/gsXy/4LF8v9/xfT/f8X0/33D - 8v95wfD/ecHx/3e/7/94wPD/dr7u/3O87v9xve//cLvv/2667v9suOz/a7fs/2u37P9ote3/ZrPr/2az - 6/9iser/YK/o/12t6P9crOf/Wqrl/1mp5P9Xp+L/Vqbh/1Wl4v9VpeL/U6Pi/1Gh4P9QoOH/T5/g/02d - 3v9Jmt3/SZrd/0eY2/9Gl9v/RJba/0OU2v9FlNb/Q5TR/0KS0f9BkdH/M4rf/0eDuf8gFhj/WFdU/0M+ - O/9BPj3/QDw8/wsJCf8JCAj/CgkJ/xUUFP8UEhL/FRMT/w8NDf8QDg7/EhAQ/zs5Of9raWr/q6er/+Le - 4f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANPQ - 0f9YVFT/V1VV/wwMDP8KBwf/BwgO/6jS4v+Hze7/jMf9/5HO9v+Ny/T/jc31/4rK8/+IyvP/isry/4rK - 8/+IyvP/hMjz/4XJ9P+CxvH/gsbx/4HF8v+BxfT/f8X0/3nC7v97w/L/esLx/3jA8P94wPD/dL7u/3O8 - 7v9wvO3/b7ru/2+67v9suOz/a7fr/2q47f9nter/ZrPq/2Oz6v9isun/Xq/o/12u5/9crOf/Wank/1io - 4/9Xp+L/Vqbj/1Wl4v9TpOH/UaLf/1Cg3/9Pn+D/UKDh/0mb3P9Lnd7/SZre/0eY3P9HmNz/RpTZ/0aU - 1/84ktb/NI/X/zyP1/9fkbv/LiU0/1daV/9PQj//QkRD/0xIR/8FAwL/CAgI/woKCv8MDQ3/CwsL/wkJ - Cf8SEBD/DQoK/wkGBv8fHR3/XFtX/z89Pf/b19r/5ODj/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF5cXf9VU1P/VVNR/w4KD/8DDQX/BAoH/32S - o/+Ny/D/jcvz/4rK8v+Ly/P/jcv0/4jK8/+MzfT/isrz/4nJ8v+HyPT/hsfz/4TI8/+EyPP/gMTx/4DE - 8f9/w/D/fMXx/3vE8P95wfD/ecHw/3jA8P92v+//c73t/3K77f9vu+z/b7vs/2y47P9rt+v/abfs/2i2 - 6/9mtOn/Y7Pq/2Ky6f9fsOn/Xa7n/1yt5v9bq+b/Wqrl/1io4/9Xp+T/VaXi/1Sl4v9So+D/UqLh/1Cg - 3/9RoeD/S53e/0mb3P9Jmt3/SJnc/0eY2v9ImNj/RJXd/zuX3P9LktD/d6HR/0FAQ/9rbGP/Uj9N/z9B - QP9FRkX/ExEQ/w0ODP8JCQn/BwkJ/wYICP8ICgr/DQ0N/w8MDP9ybG3/TktM/0pIR/9JSET/RUNC/3l2 - d//m4+T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA2dbZ/1pYWP9YVVD/U1ZQ/x0TE/8JBgv/AQoO/yYxNv+Z0vj/kND2/43M9f+OzPX/icv0/4zK - 8v+LyvP/iMjx/4jJ9f+Gx/P/hcby/4TI8/+CxfL/gcTx/4DE8f98xPD/fMXx/3rC8f95wfD/ecHx/3e/ - 7/90vu7/c7zu/3G67P9wvO3/brru/2y47P9pt+z/abfs/2a06f9js+j/YrLp/12v5/9er+j/Xq/o/1ur - 5v9ZqeT/WKjj/1en5P9WpuP/VKXi/1Ok4f9RoeD/UKDf/1Cg3/9Mn9//S5ze/0ub3P9Lm9z/RJna/0OY - 2v9FlN3/R5PM/6bF4f9EPED/eXh7/1xQT/84QDr/Rj5A/yYfG/8ICQf/CAkH/wgICP8ICgr/BggI/wkL - C/8NDw//SUZG/0pERf9IRUT/REJC/0RDPv84NzT/KScn/+Tg4v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj46O/1ZXVv9UUU3/V1RR/yAd - Hf8LCAj/CgcJ/wMHD/98pbz/m9Pz/4/N8v+Lzfn/j8vz/4rM8/+Fy/P/hczy/4bL8/+FyfT/hMf0/4PG - 8/+Cx/L/gcbx/3/F8v9+xPP/e8Py/3rC8v94wPD/d7/v/3a+7v9zvO7/dL3v/3K77/9vue3/bbjs/223 - 7f9rt+z/arbr/2m07P9ms+v/ZbLr/2Cv6P9hsOn/Xa7n/1yt5v9aquX/Wank/1mp5P9WqOL/VaXg/1Wk - 4v9TouH/UqLi/1Cg3/9Qn93/R5zj/0aZ3P9Jl9f/SZvb/3it3P/V7v3/Hhsj/6acm/9YVFT/RUFA/0VB - QP9FQUD/NDIy/w4MDP8NCwv/DQsL/w0LC/8ODg3/Dg0M/yspKP9OS0r/S0dG/01KRv9MSEf/SkZF/2Rg - YP9WUFH/3drc/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAWVlZ/1NRUP9VU1L/VFJS/zQyMv8IBgb/DQ8H/xUGDv8OFiD/l9Pl/5XT - +P+Hyfj/i8v0/4vL8P+LyvL/h8n1/4fI9P+EyPP/hMjz/4LH8v+CxvL/gcXy/4HF8v9+xPP/fMLx/3nB - 8P95wfH/eMDw/3S97/90ve//c7zu/3G88P9wu+//brju/2y47f9rt+z/arXt/2e07P9lsur/Y7Lr/2Gw - 6f9er+j/Xa7n/1qq5f9aquX/Wank/1en4v9Vp+L/U6Th/1Kj4P9Qotz/UKHg/02f4f9UoNn/Spvd/0aY - 3P+/4/v/vsTF/0A2Kv/Sysz/QUZN/0VBQP9HQ0L/Qz8+/09LSv9PTEz/KScn/xAODv8RDw//CQcH/wwK - Cf8cGBf/SUVE/05JSP9OSUj/TEhH/0dDQv9DPz7/VE9Q/0xHSP/X09X/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH17 - e/9VUlH/Uk5N/1RQT/8TDgr/BAwJ/w0HBf8tNED/l9Lw/4/J+v+QyvT/ks/3/5HM+v+Lx/n/hsry/4bK - 8v+HyvX/hcn0/4PH8v+Dx/L/gcbx/4LE9P9/w/L/fcPy/3vD8v94wO//dsDw/3S+7/9yu+3/cb3u/3G9 - 7v9vue//bbnt/2y47f9pter/Z7Xq/2az6/9js+r/YrLp/1+w6f9er+j/XKzn/1ur5v9aquX/WKjj/1Wo - 4/9QpeP/UKPc/1Om3f9Nn9z/SJ3k/1CZ2P+33PX/9fz0/zQ6Nv+wrbf/y8XQ/zU1L/9IQjr/RkJB/0ZC - Qf9HQ0L/U09O/5eUlP+fnZ3/amho/ygmJv9FQ0P/Ojc2/1VRUP9VUVD/UExL/05JSf9NTUv/UVFQ/2Zm - Zv9EQ0X/SklL/3x8fP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRRUf9TT07/UUxK/0pTUP8qLC3/DQoI/wgG - Cv8iM0L/jsDY/5LQ8f+Cy/P/hM3y/4jL7/+LzPL/isz0/4bJ9P+GyfT/hMf0/4PH8v+BxfD/gcTx/4DE - 8f99w+//esLx/3jA7/92wPD/db/v/3O97f9yvu//cLzt/2+77f9uuu7/bLjs/2y47f9otuv/Z7Xq/2S0 - 6/9js+r/YLHq/16v6P9crOf/W6vm/1qr5P9ZquP/Vqjl/1Wl4v9dqeL/WaHd/1ud2f+y1/T/7vn6/3d8 - fP9pcXT/9vb3/358fP9CP0H/R0NG/z8/P/9IREP/SkZF/0dDQv9OSkn/tbKx/6elpf95d3f/QkBA/0tJ - Sf9NSUn/TEhH/1JQT/+DgID/1NHS/wAAAAAAAAAAAAAAAH18fv+lo6X/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA08/R/1dSUf9UT0z/U01I/0xKS/9PTUv/DAsC/wsIBP8NCAf/GyY3/4arx/+ApL3/NE5d/4O9 - 3/+X0vX/iMjw/4bH8v+FyPX/hMjz/4PH8v+AxfD/g8fy/33E8P97xPD/eMDv/3bB7/91v+//dL7u/3G9 - 7f9xve7/b7vs/2+87v9tuOz/bLjs/2m37P9nter/ZbXr/2Oz6v9hsuv/YLHq/16u6f9drej/XK3m/1mr - 4v9YqOT/Xabf/3Cs3v+t2vT/4/L1/2Nvdv91eHr/+vf3/8PBwf8/PD7/PkJB/0RDQv9PRkT/SkVD/0pG - Rf9LR0b/TEhH/09LSv9RTk7/TkxM/1FPT/9samr/sa6v/+Hc3v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADY1tf/VFJS/1RRUP9UT07/Uk5N/1JN - Tv87OTj/CwkJ/wcHB/8ICQf/BQYG/wcHB/8GBgb/CAYF/wEIDP8oPU//fKjD/5bL7P+GzPT/gsjw/4PF - 8f+BwfD/gMPx/4TD8/9+vfD/fsDz/3fA8P90wu3/dr/v/3K97f9uvOz/bLzx/2m68P9tu+b/bLrn/2u2 - 6v9ptOv/Za/p/1+38P9csun/YbHo/2Cv5f9kr+L/a6bQ/5Sw0//IzeL/0NDW/0FCQv+dnJ7/+vn7/8/P - z/9KS0n/RERD/0hEQ/9JRUT/SERD/05KSf9HREP/TktL/05LTP9ZVlb/gX9//8rGyP8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGloaP9YVlb/WFZV/1dSUf9RTUz/T0tK/0tJSP8MCgn/BwcH/wUFBf8JCQn/Hx8f/wgG - Bf8TDgn/BgUB/wkEBv8GBAr/DAkV/wkTIf8tQ1b/YIag/5/V9/+R0Pf/hs3z/2+/6P9zw/L/ecDw/3+/ - 7/98v+z/ebzt/3m78P92uvT/c7jz/2228P9tt/H/bLru/2+88P9quur/d7fk/2SVuf9jfpj/a3CE/5OP - m/+ln6D/OTM1/09HSv/Ku7///fr7/7y6uv9BPz//R0ZG/0ZEQ/9OSUn/TkpJ/0dDQv9IREP/VFBP/52a - mv/l4eP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwb/A/1ZUVP9bWVj/V1JR/1NP - Tv9RTUz/SEZF/0NBQP8ICAj/CQkJ/wkJCf8zMzP/QUFB/yAkI/8FCgn/AwgH/wQKCP8GCgb/DQYB/xAL - Bv8SEgz/Eg8Q/w0ND/8IBxT/aYad/4fE6v97wvH/c77z/3S+8v9vvvH/bsDt/3LD6f94xef/fK7R/3SX - sf9TYm//S1BQ/1ZVVP9hWFn/S0dF/zMxKP8gJBX/QEQ1/4aJhP/Bvbn/zcjH/3R6d/82Ozr/SEZG/0dF - Rf9HRUX/TUtL/3d1dv/KyMn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAZWNj/1xaWf9XUlH/VFBP/1dTUv8QDg3/BgQD/wkJCf8KCgr/BQUF/wQE - BP8dHR3/RDs9/1JKTP9KQ0T/NTAx/xsYGP8NDRf/Dg8Y/xISGP8REhT/EA8Q/xIKB/8JERf/GzJA/zNR - Z/8/X3v/SWaD/0xkg/9EVm//OEBQ/zs6Qf86Nzf/KSEi/yMdIP8fHyP/Ki8y/0JIRf9VVlb/a2No/39y - e/9/cnr/aWFm/0U+Q/9JREb/UUlK/3Fqaf+enJ3/2NXX/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc2Nn/VFJR/1lU - U/9WUlH/U09O/1RSUf9OTEv/Pj4+/wYGBv8ICAj/CQkJ/wgICP8ECQT/BAgD/xARD/8vKyv/Pjk5/1BG - P/9JQzv/PTg0/zIsLf8oJSX/HSEe/wcGBf8HBAT/CAkF/wQIAf8EDAD/AQoG/wIJBf8GCQb/FBAM/0dG - Rv9xaWb/Z1xV/2FZUf9aV0v/V1ZO/01NSP9DRj//PkI6/0BHP/96enr/u7m8/wAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3d3f/XVlY/1lVVP9UUE//VFBP/1FNTP9UUE//ODQz/w0L - C/8HBQb/CgkL/wgICP8ICAj/AwMD/xYWFv8CAgL/IyAg/zg2Nv9YVlb/SEZG/zMwMf8VFRX/BQUF/wgI - CP8CAgL/CAkI/wkIB/8JBwf/GxYX/3dyc/92cXL/W1hY/0NAQf9GRET/S0hI/0RBQf9ZWVn/oJ+f/93a - 2/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABVUlH/W1dW/1dTUv9UUE//U09O/09LS/9QTk7/Hhsb/wUDA/8MCgr/CQkJ/wgICP8KCgr/HR0d/zs7 - O/8gICD/BgYG/wYGBv8HBwf/CgoK/wcHB/8GBQX/CwkJ/x4eHv8/PT3/bGZn/1NOT/9GRET/RkVF/0hI - SP9PT0//d3d3/8XExf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW0s/9WWFb/VVNS/1RQT/9MSEf/TUtL/1FP - T/9SUFD/VVJS/xgTFP8KCAj/CggI/wwKCv8PDQ3/DAoK/wwODv8HCQn/BggI/w0PD/8nKSn/T05O/2Ri - Yv9OTEz/TEpK/0xKSv9QS0z/YmBg/5WUlP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAFdaWP9XV1X/VFBP/19bWv92c3X/k5GS/3Bubv9STk3/VVFQ/zQyMv8JBwf/BwUF/wkH - B/8kIiL/PDs7/1xbW/9aWVn/UVBQ/0tKSv9KSkr/UlJS/52bnP+6uLn/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA49/h/1RUU/9DPz7/TEhH/2Rj - Zf/Kycn/cW9v/z03OP9YVFP/VlFS/1VQUf9aVVb/WFNU/1VQUf9XUVL/W1VW/21oaf+koKH/2NXW/wAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAfHt7/0E8Pf9BOzz/Pjw7/1tZWP9XVVT/TUtK/1pYV/9VU1P/WVdX/1VT - U/9ubGz/6eXn/+vn6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPTs7/xsW - F/8NDAz/NDIy/1ZVVf9jYWH/mJeX/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f3//V1dX/yoqKv/V0tT/AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMbD - xf9aXFz/Zmlq/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////w////////// - /////////+AP//////////////////8AB//////////////////4AAf/////////////////gAAD//// - /////////////AAAA////////////////4AAAAH///////////////wAAAAB///////////////AAAAA - AP/////////////+AAAAAAD/////////////4AAAAAAAf////////////gAAAAAAAD////////////AA - AAAAAAA///////////+AAAAAAAAAP//////////4AAAAAAAAAB//////////AAAAAAAAAAAP//////// - +AAAAAAAAAAAD////////8AAAAAAAAAAAAf///////wAAAAAAAAAAAAH///////AAAAAAAAAAAAAA/// - ////AAAAAAAAAAAAAAP//////4AAAAAAAAAAAAAD//////wAAAAAAAAAAAAAAf/////8AAAAAAAAAAAA - AAH//////AAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAP/////8AAAAAAAAAAAAAAB//////AAAAAAA - AAAAAAAAf/////wAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////gA - AAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA// - ///wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAA - AAAB/////gAAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAA/////4AAAAAA - AAAAAAAAAP/////AAAAAAAAAAAAAAAB/////wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAAAD/////g - AAAAAAAAAAAAAAA/////8AAAAAAAAAAAAAAAH/////AAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAP - /////AAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAH/////gAAAAAAAAAA - AAAAB/////8AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf/////AAAAA - AAAAAAAAAAH/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////wAAAAAAAAAAAAAAB///// - 8AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAD/////8AAAAAAAAAAAAAAA//////AAAAAAAAAAAAAAA - H/////4AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAP/////wAAAAAAAAAAAAAAD/////+AAAAAAAAA - AAAAAAf/////gAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAP/////4AAA - AAAAAAAAAAAD//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAA//// - //gAAAAAAAAAAAAAAP/////8AAAAAAAAAAAAAAB//////gAAAAAAAAAAAAAAf/////4AAAAAAAAAAAAA - AH//////AAAAAAAAAAAAAAB//////4AAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAH//////wAAAAAAA - AAAAAAD//////8AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAP//////8AAAAAAAAAAAAAD///////AA - AAAAAAAAAAAA///////4AAAAAAAAAAAAAH//////+AAAAAAAAAAAAAB///////wAAAAAAAAAAAAAf/// - ///8AAAAAAAAAAAAAH///////gAAAAAAAAAAAAB///////8AAAAAAAAAAAAAf///////wAAAAAAAAAAA - AH///////+AAAAAAAAAAABz////////gAAAAAAAAAAH/////////4AAAAAAAAAA//////////+AAAAAA - AAAD///////////gAAAAAAAAf///////////8AAAAAAAB/////////////AAAAAAAP/////////////4 - AAAAAA///////////////AAAAAH///////////////wAAAA////////////////+AAAD//////////// - /////gAAP/////////////////8AA///////////////////gP///////////////////4f///////// - //////////+P//////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////8oAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD///8BkZGRB7+/vwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADMzMwFt7e3IKyorFOHh4drh4eHq5qammP///8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAGcnJwNnp6eMoyMjFeFhYWfdHNy2GNhYfdLSUn9Y2Bg/3NxcM6np6cdAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Aqmp - qQmurq4msK2tYYuJiYCBgYG3a2pq5ktKSvg7Ojr+NDIx/0RDQv9eXFv/bGlo/1NRUPmIiohwf39/AgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Bv7+/BK2t - rRmRkZE4nZ2deIWFhbVub2/dXFxe+ERHSP9jYmT/VFJT/1BPT/9qZmn/gHx9/5WQkf+Yk5L/dXBv/0RD - QP9rbGnPpKSkHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoqKiC6Ki - nCyjoKBnjYyMoHh4eNFlZGTqeXZ2/UZFRv80Nzj/Ojw//1VVWP+Bfn//k46O/5mUlP+clpb/nJaW/5uV - lf+Uj47/bmpp/0JAPv9ERkP6iIiKjL+/vwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wG/v78Mv7m5LI+P - j0CLiIh5eXl5rnRycuFfXV/6RkdJ/zY3Ov83Njn/e3Z3/3d0df9zcHL/jYiK/5eRk/+dmJf/npmY/5yW - lf+Yk5P/ioSF/3dycv9qZmb/TkpJ/0dEQv8zMjD/UlJS1KOjoyoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqgOmpqYXlpGWMZeV - lW+Ih4e3fHt85l9fX/BHR0j+PT5B/0RFR/9VVVf/b25w/4F+gP+QjI3/n5qa/6Cbm/+gm5v/n5qa/52Y - mP+WkZD/iIOD/3Vwb/9nYWH/Vk9P/05JSP9pZGT/aGNj/0dDQv8+Ojn/Q0FA/o2Li5a2trYHAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADa2toHtLGxUpCP - j5t7eXrMbWxu51JRU/w7PUH/LjE0/yotMP9eXmD/fnx+/5OQkf+gnJ3/o56f/6GbnP+hnJv/n5qZ/5uV - lf+Qi4v/gHt6/3Fra/9kXlz/W1RT/1RNTP9IQkH/PTg3/0VBQP9VT0//VVFS/1RSU/9FQUH/QDw7/2xr - a+a2trYxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - /wSLiIhhXFxe1kdIS/9CQ0f/RkdL/2FhZP9xcXT/dnR2/4eEhv+bl5f/oZ2d/6Kdnv+jnZ7/oZyc/5eR - kv+BfHv/dnBv/2JcW/9RTEz/WFRT/3Rxcv9bV1f/Pzs5/y4pKP8oJCP/KyYl/zk0NP86NTX/UExN/2Zj - ZP9KRkX/RkJB/09NTfuBf39yf39/AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAN+/3wh5dne5SklK/2xtcP+MiYz/npqd/6Wgov+kn6D/o56f/6Gcnf+emJn/mJKT/4uG - hv+GgIH/gHp6/2diYf9XVFL/YV5f/1lUVP83MjL/RkBA/21qav9STk3/Ozc0/yciIP8gGxr/HhoZ/x8a - Gv8iHh7/KiYl/zw4N/9KRkX/SERD/z06Of9jYmLPpKSkHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAALm5uQuZl5i9mpaW/56amv+loKD/pJ+f/6Gcnf+blpb/jomK/4V/ - gP9+eXv/V1RU/0VDQv9DQED/Uk5N/1pVU/9gXV3/g4aK/6ChpP9hXl7/Vk9N/2FdXP+Ylpf/QDs6/yId - HP8fGxr/Hhsa/x4bG/8gHh7/Hxwb/z05OP9TTkv/TUhH/0I+Pf9LSEj6kI6Ob////wIAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALawsCqemZvjnZiZ/5yYl/+UkI//hYGA/3dy - cv9qZGT/bmtq/3d3d/++v8L/d3l9/zs9Pv8+Pj//Vlda/1RVV/9ISEr/VFdc/3Fzdv9dWFf/YFlW/1NN - S/89OTn/Kigp/x0aGv8ZFxb/GhgZ/yMjLv8lJTX/JCAg/0M9PP9bVVH/TUlH/0pGRf9APTz/bmxuzrOz - sxsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKyorFB8eHn0eHNz/3Fs - a/9iXl3/T0pJ/1pTUv9JREP/YF5f/4SEi//KztT/zdPc/6WstP+ttLz/wMjS/4yTmv9DRkn/JSUm/yAf - IP8tKSj/V1BP/1dPT/8iHh3/KSo0/yAdHv8eGxr/IB8g/yopNP86Nz//SkVC/1dRTf9cVVP/VE9O/0xI - R/8/PDv/SUhH839/f04AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6M - jHhVUVD6amZm/3Zycf9aVVT/UExK/1hTUf9QTUz/VVJW/5mco/++yNH/ytTe/9Ha4//R2uP/zdfg/7a/ - x/9qcXf/NzlB/yAfIf8eGxv/OjU1/0pFRP8mIiL/Ozk+/zg0M/87NjX/SUNC/zk0M/9JREL/V1BO/09I - Rv9ZU1L/Yl1c/01JSP9GQkH/Ozo5/2VlZbCjo6MOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKSkpB99eXm1ZmFh/mNfXv+Vk5T/eHV1/1BLSP9bV1b/nZ6j/9DY4P/S3OX/09zl/9be - 5v/W3+b/0tvj/8vU3f+QmaD/R0xV/xscIP8XFBX/GRcW/yomJ/84Nzr/REJG/zk1M/87Nzb/SkVE/0I9 - PP9AOzr/UkxL/01HRv9RTEv/VlFQ/05JSP9JRUT/PTo5/1BNTPKioKBm////AQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wGNjY02aGRk4CYlJP9BQD//REFA/zg0M/9hX1//x87U/9Pc - 5P/AytP/y9Td/9Xe5v/O193/rLK4/5+jqP9tcHf/NjpD/xoaG/8XGBr/Fxca/xocJf8lLk7/MzZK/0I9 - PP9AOzv/Pjk5/zw4N/8+OTj/QTw8/0M/Pv9GQUD/SURD/01IR/9IQ0L/Qz8+/z47Ov9vb2+1nJycDQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZkFcGtrbzY0M/giIB//MC0s/zo2 - Nf99foH/19/m/8rT2/+1vsf/wszV/8jR2v90eHz/ZGBj/3p1eP9ZWmD/Nj5O/yIlL/8aHCX/ICQ0/yUt - TP8nMFL/JCYw/yMiI/8fHR3/HRsb/x0cG/8bGRr/HBka/yEeHv8oJCT/Mi8t/0E9O/9JRUP/R0NC/z88 - O/9WVVXwkJCQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiYmJGmdk - Y8ggHh3/GhgX/zIvLv+OkZP/1+Dn/8rU3P++yND/0Nni/52lq/9TUVP/fnt9/83Nzv++wML/m6Kq/3N8 - jP8oLkP/KC9C/yYwQf8oLDP/MzU6/yMmKv8aGx//HiAh/xsdHf8PEBD/Dw4O/xEREP8VExP/FhQU/x0a - Gv81MTH/R0NC/0hERP9XVVX/eHd3r7a2tg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA////AZORkWRIRUTyExER/x0bG/94en7/09vj/9ji6f/X4ej/1t/n/5edpP+CgIL/0M/Q/6+y - tf+vsLL/yMnM/+Lk5/+dpbP/dYKS/1Zfaf89UWb/SnOW/zxqkv8zYYn/Lld+/yZIav8cM0v/ER0r/w8T - Gf8RERL/FBMT/xEPD/8YFhb/Pzs6/0pGRf9CPz7/WVdX76Ofo0sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI2NjQljX1+LKicn/hEQD/9RUlX/y9Pa/9ji6f/X4ej/1+Hp/7vD - y/+SlJf/w8LE/6iqq//KzM7/9fb2//X29v++v8H/ZnyM/4mgs/93iZv/T3qi/z+Hwv88jM3/OIbK/zaC - xf81fL7/MHCv/ylflP8gRGj/FiQ0/xERFf8eGxv/QTw8/0ZCQf9HQ0L/RUJB/3Bvb5OZmZkFAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACalpY9WlZV4hYUE/8sLCz/tLzB/9fh - 6P/M1d3/1N3m/87Y3/+krbT/TE9S/0lQWP+Nr8f/vN3y/8Lf8v/T5fH/t8DE/3aEkP+gsLv/tbvB/2V/ - mP9IhLb/PIjK/ziGyv82gsf/NX7D/zR6wP8ydrv/Lmup/yVNdv83PEX/R0NC/2llZv9RTEz/RUJB/1dW - VeCbm5s7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38EgHx8fTc0 - NPcfHx//lpqe/9Xd4//b5Ov/093l/7W/yP+6xMv/SVhk/12Rtv9ttuj/a7fr/2a06f9stun/hcHp/6PJ - 4v/E2ef/1eHo/7nBxv+Ej5f/YISl/z+Fwv84hcr/NYHH/zR9w/8ye8D/MXi9/zB0uP8zZJT/PEtb/15b - XP9NSEf/SUZF/0dFRP6CgoKezMzMBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAhYWFFVdTVL4eGxv/Gxsb/15fYf+usrj/zdPZ/8/X3f91hpP/aKHF/3e97/9wu+3/a7js/2a0 - 6/9gsen/W63m/1mp4/9gquP/bK7g/5S/4P+kv9L/nK+//3mYtf9JiMD/OYPG/zaBxv8zfcL/Mnm//zF3 - vP8vdbn/MGun/zhQaf9APj//WFZV/1VTVP9aWVnek5OTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAYeBhFVOS0rtFRMT/w0NDf8xLzD/R0dH/292e/9xob7/fMLw/3nA - 8P90ve7/b7vt/2u37P9ls+r/XrDo/1qr5f9Wp+L/UaLg/0+f3P9Qndn/WJ7X/2ej1P9sm8X/WY29/ziE - x/80gMX/M3zB/zJ5v/8wd7z/L3W7/zBurv84UGv/Tk1O/3Fxc/9NTEz9gX9/iszMzAUAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/fwhtaGiVMC0t+xAPD/9BPj7/LCkp/zlH - T/9rm7n/drXd/3vA7v93v+//crzu/2257f9ptuv/ZLPq/16v6P9bquT/Vp7U/2Sj0f9SirX/Q36v/z+F - v/9Bjs7/RpDQ/zyIzP82g8j/NIDF/zN9wv8yeb//MHa8/y50uf8wbKr/PE1e/3Z2d/9ZWFr/aGZm36ur - qy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpaWkiVFFR0kZF - RP9oZmT/XlpZ/0RFRf8yODv/NURN/0Jdb/9WgJ3/YJe6/2ut2f9tt+r/abbr/2Wu4f+Vw+P/dJCo/3mX - tf9kg6H/TmmF/yE4Uf8pTnD/OoG5/zyLzv84h8z/NoTJ/zSAxf8zfMP/MXnA/zB3vf8vdbr/M2SU/1VZ - Xv9bWlr/V1VV/ZGQkYrMzMwFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB/f38CgHx8dV1ZWPphXl7/aGdp/3WRpP9tkqr/Y4Wb/1l3if9LY3P/PlNg/0pne/9pq9j/arXo/1SD - p/92n8n/ZZjP/1SGu/9XkMr/XJbR/017rf81XYf/JUVi/z6DwP88i9D/OIfM/zaEyf80gMf/Mn3F/zF6 - wf8web7/L3O1/z9SZf9VUlH/WFZW/29vb9KXl5cbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAqaCgG21pab1VUlL/WmFn/4rB5P+Ky/T/iMny/4TH8f9+wOv/ebvm/3e4 - 5P90u+z/a7Hh/0iBt/9FgcP/eaLL/6u3zP+ftNL/orLM/4Gewf9ZltL/RHaq/0R5q/8/j9P/O4zQ/ziI - zf82hcr/NIHH/zJ9xP8xe8P/L3nB/zVaf/9OS0r/YFxb/2FeXfeDgIBj////AQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeEhE9iYF7xXGRp/4i/5P+MzPT/isrz/4fI - 9P+Dx/P/f8Xy/3rC8f93v+//aK/j/0OGyP9rlcP/iJa7/9TQ4/+0tb3/ubbD/6q00/93n8f/WZPO/0+P - yf9Ek9f/Po/T/zuM0P84ic3/NoXK/zOCyP8yfcf/MHvE/y1Ygv9EQUL/VVFQ/2ZkY/97enrGn5+fGAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwsA1xb22XUVRV/Xqp - yf+NzPX/jMv0/4nK8/+FyPP/gsby/3/E8/96wfH/bbbp/0aKy/9yncr/hpnF/7yq0v+9uMj/1dPi/7bD - 4v+EqMz/YJvX/0+a3P9Gl9n/QZPW/z6P0/87i9D/OIjO/zWEzP8zgcr/MX/H/zFbg/88Ojr/Ly4t/3t5 - ef+NjY33k5aWUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACMhYUoVlNTz115jP+NyvH/jcz1/4vL9P+JyvP/hcjz/4HF8v99w/H/d7/v/1mf2v87fMD/YZLJ/5mi - xf+XqNL/qsDe/3yYu/9Pjc3/U5vd/06d3f9Jmtz/RZbZ/0GS1v8+j9P/OovR/zeHzv80hM3/MX3E/zdQ - a/9CPj3/QD08/4qHif+hoaT9ko+SYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABbGpnZ0NLT/h1pMP/jsv0/43M9P+Ly/P/h8jz/4TH8/+AxPH/fMLw/3W9 - 7v9dpN3/V5XR/2aazf9JhcT/W5PO/2ug1P9Smtz/U6Hg/1Gg3/9Nnd7/SZjc/0SV2P9Bktb/PY7S/zqK - 0P84h8//M3Kr/ztCS/89OTj/QDw7/3h2d/+mpajqqKOoOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf39/FE1NTK5BT1n+gLXX/47M9P+My/T/icr0/4bI - 9P+DxvL/f8Tx/3nB8f91v+//brfr/2Ot5v9dp+L/XKbi/1up5f9aquX/V6fi/1Oj4P9Pn9//TJzd/0eY - 2v9DlNj/P5DV/z2N0/84g8b/NlJs/zk2Nv8fHRz/KCQk/05LSv+Wk5bfkpKSIQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHBwcERFQkTsPU1Y/4Cy - 1P+Ny/P/isvz/4jK8/+FyPP/gcXy/33D8v95wfD/dr/v/3C87v9tue3/abXs/2Oy6v9druf/Wank/1am - 4v9SouH/T5/g/0qa3f9Gl9v/QpTX/0KNzv9AZIf/Pz9B/yEfHv8PDg7/FxUV/yspKf99env0ysbKTQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALm5 - uQt2dHSkPTw6/DRASP9qlbH/isbt/4rL8/+HyfP/hMfy/4DF8v98w/H/eMDw/3S97v9vu+3/a7fs/2a0 - 6v9gsOn/XKzm/1io5P9UpeL/UaHg/0yd3v9Jmtz/VpzW/2KBnf9RUFP/MzAv/w0NDP8MDAz/Liws/0VC - Qf9gXV39t7S0YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABzc3MhWVdXkUI/P/QoLC7/U3GE/4bB5/+IyfL/hsnz/4PH8/+AxfL/e8Lx/3a/ - 8P9yvO7/brnt/2q27P9ls+r/X6/o/1ur5v9XqOP/VKTg/1yl3v93q9L/iZup/2JgYv9KRkX/WldW/zg2 - Nv8wLSz8UE1L9VFPTdhgXl7llpCTUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAm5ubF3JvbdFKR0X/LC0t/zVIVP9NbYD/WoGa/3Ko - y/96ueH/f8Pu/3nA7/91v+7/cLzu/2y57P9oter/Y7Hn/2Co3f9npdP/gavP/5etvf+NkZT/X15e/lBM - S/xTT0/oc29vzWpoaKF9eXl+dHBwRnt7ex94eHgzf39/DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo6OjDnNycrlWUlH/Ozg4/w8P - D/8YGBj/Gxwd/yAmLP8uPEf/QVpr/1aEov9knsb/YpzD/2KStP9XepL/WHKE/1hmcP94fIL9iIWI8Ht6 - euNgXV28Yl5ehHFra2GCgoIzlJSUGKqqqgP///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYeE - hFVdWlntS0hH/y0sK/8PDg//FBMS/yIfH/8sKSn/IiAg/xMWGP8fJyv/LTM3/UpKS/hUUVDoWFdUz2pq - Z6dzcXF3bGhoPZSOlCuLi4sLqqqqAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAH9/fwhvb22cVlNS/ltZWf86Nzf/GRcX/x8dHf8rKyv+ODg49UZGRt9NTEyxXFhYh1pa - Wkx/f380a2trE8bGxgkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwzUk9O2VpYWPxcWVnoUExNv3BtbbZ6dHZ7iYWJUHh4 - eCKioqILf39/AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqqqoDa2lrg1xaXJhzc3MzbW1tDp+f - nwj///8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlJSUDHFx - cQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////RwP////4//9HA////8B//0cD///8AH// - RwP//8AAP/9HA//8AAA//0cD//AAAB//RwP+AAAAH/9HA/AAAAAP/0cDwAAAAA//RwOAAAAAB/9HA4AA - AAAH/0cDgAAAAAP/RwOAAAAAA/9HA4AAAAAD/0cDgAAAAAH/RwOAAAAAAP9HA4AAAAAA/0cDwAAAAAD/ - RwPgAAAAAH9HA+AAAAAAf0cD8AAAAAA/RwP4AAAAAD9HA/gAAAAAH0cD/AAAAAAfRwP8AAAAAA9HA/4A - AAAAD0cD/wAAAAAHRwP/AAAAAAdHA/+AAAAAA0cD/8AAAAADRwP/wAAAAANHA//gAAAAA0cD/+AAAAAD - RwP/8AAAAANHA//4AAAAA0cD//gAAAADRwP//AAAAANHA//+AAAAA0cD//4AAAA/RwP//gAAB/9HA/// - AAD//0cD//+AD///RwP//4D///9HA///z////0cD////////RwP///////9HA////////0cDKAAAACAA - AABAAAAAAQAgAAAAAACAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACpqakJpaWlKIuH - h02GhoZsnZ2dFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmZmZBbe3txmIiIg2eHh4cmVk - ZK1ZV1fhUU9P92VjYvd6eHhm////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wKjo6MOkZGRKpGRkWJzdHSdY2Nl1GFh - YutYVlb9VlRV/29rbP+FgYD/ZmJi/11dWsecnJwaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Bn5+fCJOTkxqJiYlDg4GBiGtrbMFVVVblbmtt+kpK - TP9ZWFv/gH1+/5SQj/+ZlJT/l5GS/4qFhP9dWVj/QUE/+m5xbnN/f38CAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+/vwSZmZkUjY2NNoaGhnd0dHSyWVla1VJSVPFXVln+YmFk/3Jw - cf+Uj5D/l5KS/5uVlv+XkpH/ioWE/3lzc/9gWlv/YVxc/1ZSUf8/PDv/VFJS1KWeniUAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACflJ8YgoKCiWdlaMtYV1vrTk9S/UVGSf9jY2X/ioeI/5uX - mP+hnJ3/m5WV/5KNjP+BfHz/dG9u/2hjYv9RS0r/QDs6/zs3Nv9MR0b/WVVW/01JSf9KR0f8fX19dv// - /wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH14e3JVVVf3bm1w/4iGif+XlJX/mpaX/5yX - l/+WkJH/jYiI/4N/fv9oZGL/ZWFh/0hDQ/9VUVH/ZGBg/zczMf8jHh3/Ix8e/ygjJP87Njb/SkZF/0VC - Qf9YVVXHlJSUGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8CnJmZj5mVlf+gnJz/m5aX/4+K - iv+BfHz/jImK/1lXWP9CQED/UU9O/1lXV/+Bg4f/cW5v/1dRT/9uamr/NTEw/x4aGf8dGhv/IR8j/yck - I/9QSkj/S0ZF/0dERPh9fX1m////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqg+KhobBgn19/3Nv - bv9gW1r/WFNS/2poav+ztrv/qK20/4iOlP+YnqX/VFdb/zM0Nv85Njb/WFFP/zUwMP8mJSr/Hhsa/yIh - JP8xMDv/Qz48/1lTUP9RTUv/REA//1hYVryIiIgPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoqKiFmto - Z8FtaWn/bmlp/1tXVf9VUlH/e3uA/8DJ0f/P2OL/0tvk/8rU3f+IkJj/NDc9/x0bG/81MTH/NDAw/zs4 - Ov84MzL/Qz49/0I9PP9TTEv/VE5N/1hUU/9IREP/REJB8Xd3d1P///8BAAAAAAAAAAAAAAAAAAAAAAAA - AAD///8BhYGBQ1hTU+dOTU3/T0xL/1lXVv/Axsz/y9Td/8/Y4f/O197/tbvB/4aMk/8zNz7/GBga/xkZ - Hf8nKz3/OjlE/z04N/8/Ozr/PTg3/0Q/Pv9HQkH/TEhG/0pFRP9BPTz/YV9fupmZmQ8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACZmZkFXVlZgygmJfwtKSj/bGxu/9DY4P+9xs//xs/Y/4KGi/96dnn/gYKG/09W - Yv8jJzP/Iic6/ycuR/8pKzH/ISEh/x8fH/8bGhr/GhkZ/yEfHv8tKSj/QDw7/0VBQP9QTk7xgX2BTQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQiYklSkZF0hoYF/9iZGb/0tvi/9Hb4//Gztf/gICD/7i3 - uf+5u73/w8bL/4+WpP9ZZHT/PElY/zxadP8sTmv/J0Rf/xsvQ/8SGyb/EhQX/xQTE/8dGxv/Qj4+/0pG - Rf9pZmaxsLCwDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/fwJoY2NaKyko9To7PP/EzdP/1N7m/9Hb - 4/+ip6z/mJib/6mxt//l7vP/0tjc/4CRnv9/k6T/Y4mr/0GHwv85hcj/NXy+/y9uq/8nWIj/GzRO/yEk - Kf9FQUH/S0dH/05KSut3d3c8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJuNjRJVU1OvKCco/qOq - rv/U3eT/zdbe/7K8w/9PY3L/a6PL/3/A7P+Hw+z/l8Db/6rD0/+9ytP/gZao/1KHtv85hcf/NYDF/zN6 - wP8wc7b/M16K/0tTXf9WUlL/SEVE/mloaKapqakJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG9r - azk3NTXlKioq/3d5fP+prrP/iZ2s/3Gu1v9zvO7/a7js/2Oz6v9drub/Yazk/26u4P+Fs9X/gqbF/16S - wf9AhMP/NH/E/zJ5v/8wdbr/Mmif/zxKWf9ZV1f/V1ZX539/fzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAmZmZBWFdXYAhIB/6LSsr/zc3Of9ghZz/dbTe/3a97P9xu+7/abfs/2Gx6f9crOT/WJ/U/1eV - xv9Hhrr/S43F/0iOyv83hMj/NH7E/zJ5v/8vdbv/MWig/1BaZv9jYmP+bm5tmra2tgcAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAa2trGlNQT8ddWlr/XFxd/0tZYv9GXGv/TW2D/1aCoP9oqtf/ZrDj/3yt - 1P9ulbn/ZI23/0ZtlP8sUXT/NnWq/zqJzf82hMn/NH7F/zF5wf8wdrz/OWKK/1lZWv9iYGDmkZGRMwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8BeHZ2X1tYWPNqfIn/hb3h/3643P9zqs7/aZ2//26v - 2/9ho9P/ToS9/3yhyv+Kp8z/iKXI/1iKvf89bZv/QIrK/zqKzv82hcr/M3/G/zF7wv8xb6z/SU9W/11b - Wv1ycHCBqqqqAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRf38OaGVlrWV6h/6LyfH/isr0/4TI - 8/9/xPL/ecDw/12k3P9ik8f/oKbK/8G+zP++vtD/iqrQ/1qUzv9Hk9T/Po/T/zqKz/82hcr/MoDI/y90 - tf87RVD/U1BP/3t6etmUlJQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2dnY2WGFo34K3 - 2/+MzPT/icrz/4PH8/9+w/H/a7Pn/0yLyP96mMj/oanO/6y82P9omMr/VZzc/0qa2/9DlNj/Po/T/zmJ - z/81hMz/M3Ov/zxCSP9QTU3/l5aY9pGRlUYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVV - VQNYWFh8XHmL+ovG7v+My/P/h8jz/4LG8v97wfD/aLDl/2Oh2P9XldD/YJzV/1mf3P9TouH/Tp7f/0mY - 2/9Ck9f/PY3T/ziHzf82XYL/NzQ1/0ZCQf+TkJPmoKCgKwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGJiYhpJS07HX4CW/4nF7P+JyvP/hcjz/4DF8v95wfD/c7zu/2u26/9lsur/Xq7n/1io - 4/9SouH/TJ3e/0aX2v9CktX/P3am/zc8Q/8ZFxf/IiAf/2lnZ+uwsLA0AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA////AW5ublxBQ0TnTWZ3/3+22P+IyfP/g8fz/37E8f94wPD/cbvu/2u3 - 7P9jsun/XKzm/1an4/9RoeD/VJ/b/2WTuv9UWWH/MzEw/xcWFf86Nzb9W1hX856ankcAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmZmBWtoaGRIRkb5PEtU/1uBmf9pmrn/d7Pa/3q+ - 6v91vu7/b7rt/2i06P9gq+H/YqTW/3eozv+Gm6z/aGls+VNQT+tlY2PLWFRUqGJdXXJmY2ZchISEGwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgoKCMV9bWuQ0MjH/FhYX/yAi - Jf8vOD//Ok9e/0lyjf9SepX/VnCD/Vhqd/RtdXzdgoKFu29vb45gXV1XdXBwNH9/fxSqqqoGAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZkFa2dng1NQ - UPw3NTX/HRsb/ywqKvswMDDrNzc3y0ZGRpxfXVtwaWllRHhwcCJzc3ML////AgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB7e3shVlRUyFxaWr9TUVGHcG1tZHVwcDR/cn8Uf39/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAH9/fwJubm4ua2trE////wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////+D///4 - Af//gAH/+AAA/8AAAP+AAAB/gAAAfwAAAD8AAAA/AAAAHwAAAB+AAAAfwAAAD8AAAA/gAAAH8AAAB/AA - AAP4AAAD+AAAAfwAAAH+AAAB/gAAAf8AAAH/AAAB/4AAAf/AAA//wAD//+Af///h/////////////ygA - AAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA////AZSUlAx5eXksf3h4JgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGR - kQd/f38ecW5xSmtpa4NlY2S8a2dn52VkY7l4eHgTAAAAAAAAAAAAAAAAAAAAAP///wGNjY0ScXFxOGNj - Y2xpaGmpbGps2nl2d/V+env+gn59/3Rvb/9RTk73XlxcYf///wEAAAAAAAAAAAAAAAB/eXkqbm1wv3V0 - du14dnf9hoKD/4WAgP90cHD/aGNj/0E8O/83MzL/SUVF/1JQTsJ4eHgTAAAAAAAAAAAAAAAAjomJXYaC - gvt6dXX/ioiL/3+Bhf9pam3/VFNU/09KSf8qJyf/JyQn/0Q/Pv9NSUj1XltbVAAAAAAAAAAAAAAAAHZz - c0tfXFzuXFlZ/6yyuP/I0dn/mZ+m/y4vM/8sKzH/NjM2/zw3N/9JQ0P/S0dF/05MTLV/f38OAAAAAAAA - AAB/f38IQT8+mE5NTv3EzdT/qrC2/5ubn/90eIL/PEVX/y9BUv8jMkH/HiMq/yooKf9HRETyZGRkTAAA - AAAAAAAAAAAAAF5YWCtCQkLas7vA/7a+xv+Gna7/psri/4qnvP9ymLf/QX+3/y5qo/8qTG//SEtQ/1ZT - U6tzc3MLAAAAAAAAAAB/f38CSENGbUpKS/dzgo7/bqrS/2q16f9nsOT/baXQ/1iOvP89hMX/Mnm9/zdk - kv9WW2LubGxsQgAAAAAAAAAAAAAAAF1dXRNZVla6ZXyM/2aTsf9mocj/ZKHR/3abw/9Ygar/Pn+6/zeE - yf8yer//RF97/2ZiYqCRkZEHAAAAAAAAAAAAAAAAaGRoR3Sas+uIyfL/fcLw/2Og1v+XqMz/jqvQ/1CW - 1P8+j9P/NoTL/zdbfv9pZ2jhk5OTJgAAAAAAAAAAAAAAAG1tbQdcbnqSeq3O/YXH8v92vOz/aqzh/2Kn - 4P9TouD/SJja/z+Dvv8vPUv/VVJS5pWVlSkAAAAAAAAAAAAAAAAAAAAAXl5eI1JfZslkjab/cqzR/3K3 - 5f9nseT/XaTX/2WcxvpcbX3rPDs8zk1MSqGDe3shAAAAAAAAAAAAAAAAAAAAAAAAAAFhXlxpODk59y83 - PPVAVGLeVG6AuWV3hY18gopaYmJiMXJychR/f38GAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAZmZmFFlW - VmpOS0tEVFRUIWZmZgr///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/h8mAPAPJgAAByYAAAcmAAAH - JgAAAyYAAAMmAIABJgCAASYAwAAmAOAAJgDgACYA8AAmAPAAJgD4HyYA/f8mAA== - - - \ No newline at end of file diff --git a/Forms/SelectCategory.Designer.cs b/Forms/SelectCategory.Designer.cs deleted file mode 100644 index a907285..0000000 --- a/Forms/SelectCategory.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Этот код создан программой. -// Исполняемая версия:4.0.30319.42000 -// -// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае -// повторной генерации кода. -// -//------------------------------------------------------------------------------ - -namespace TLO.local.Forms { - using System; - - - /// - /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - /// - // Этот класс создан автоматически классом StronglyTypedResourceBuilder - // с помощью такого средства, как ResGen или Visual Studio. - // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen - // с параметром /str или перестройте свой проект VS. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class SelectCategory { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal SelectCategory() { - } - - /// - /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TLO.local.Forms.SelectCategory", typeof(SelectCategory).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Перезаписывает свойство CurrentUICulture текущего потока для всех - /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/Forms/SelectCategory.cs b/Forms/SelectCategory.cs deleted file mode 100644 index 292bd19..0000000 --- a/Forms/SelectCategory.cs +++ /dev/null @@ -1,207 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.SelectCategory -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; - -namespace TLO.local -{ - internal class SelectCategory : Form - { - private static Logger _logger; - private IContainer components; - private TreeView treeView1; - private Button _btCancel; - private Button _btSelected; - private TextBox _txtFrom; - - public Category SelectedCategory { get; private set; } - - public List SelectedCategories { get; private set; } - - public SelectCategory() - { - if (SelectCategory._logger == null) - SelectCategory._logger = LogManager.GetLogger("SelectCategory"); - this.InitializeComponent(); - this.SelectedCategories = new List(); - } - - public void Read() - { - try - { - ClientLocalDB.Current.CategoriesSave(RuTrackerOrg.Current.GetCategories(), true); - } - catch (Exception ex) - { - int num = (int) MessageBox.Show("Не удалось загрузить список категорий.\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - SelectCategory._logger.Error(ex.Message + "\r\n" + ex.StackTrace); - } - Category[] array = ClientLocalDB.Current.GetCategories().OrderBy((Func) (x => x.FullName)).ToArray(); - foreach (Category category3 in ((IEnumerable) array).Where((Func) (x => x.CategoryID > 999999)).OrderBy((Func) (x => x.FullName)).ToArray()) - { - Category category1 = category3; - List source1 = new List(); - Category[] categoryArray1 = array; - foreach (Category category4 in ((IEnumerable) categoryArray1).Where((Func) (x => x.ParentID == category1.CategoryID)).OrderBy((Func) (x => x.FullName)).ToArray()) - { - Category category2 = category4; - List source2 = new List(); - Category[] categoryArray2 = array; - foreach (Category category5 in ((IEnumerable) categoryArray2).Where((Func) (x => x.ParentID == category2.CategoryID)).OrderBy((Func) (x => x.FullName)).ToArray()) - source2.Add(new TreeNode(category5.Name) - { - Tag = (object) category5 - }); - if (source2.Count() != 0) - source1.Add(new TreeNode(category2.Name, source2.ToArray()) - { - Tag = (object) category2 - }); - else - source1.Add(new TreeNode(category2.Name) - { - Tag = (object) category2 - }); - } - if (source1.Count() != 0) - this.treeView1.Nodes.Add(new TreeNode(category1.Name, source1.ToArray()) - { - Tag = (object) category1 - }); - else - this.treeView1.Nodes.Add(new TreeNode(category1.Name) - { - Tag = (object) category1 - }); - } - } - - private void _btCancel_Click(object sender, EventArgs e) - { - this.SelectedCategory = (Category) null; - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - - private void _btSelected_Click(object sender, EventArgs e) - { - try - { - if (this.treeView1 == null) - return; - TreeNode selectedNode = this.treeView1.SelectedNode; - if (selectedNode == null) - return; - Category tag = selectedNode.Tag as Category; - if (tag == null || tag.CategoryID > 999999) - { - int num = (int) MessageBox.Show("Не выбран раздел или выбран корневой раздел\r\n(Корневой раздел нельзя выбирать)"); - } - else - { - this.SelectedCategory = tag; - this.DialogResult = DialogResult.OK; - this.Close(); - } - } - catch (Exception ex) - { - int num = (int) MessageBox.Show("Непредвиденное исключение\r\n " + ex.Message); - } - } - - private void _txtFrom_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode != Keys.Return) - return; - if (string.IsNullOrWhiteSpace(this._txtFrom.Text)) - return; - try - { - if (this._txtFrom.Text.Split('=').Length != 2) - return; - IEnumerable> categoriesFromPost = new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass).GetCategoriesFromPost(this._txtFrom.Text); - this.SelectedCategories = ClientLocalDB.Current.GetCategories().Join, int, Category>(categoriesFromPost, (Func) (c => c.CategoryID), (Func, int>) (t => t.Item1), (Func, Category>) ((c, t) => c)).ToList(); - List> result = new List>(); - foreach (Tuple tuple in categoriesFromPost) - result.Add(new Tuple(tuple.Item1, 0, tuple.Item2)); - ClientLocalDB.Current.SaveSettingsReport(result); - this.DialogResult = DialogResult.OK; - this.Close(); - } - catch (Exception ex) - { - int num = (int) MessageBox.Show(ex.Message); - SelectCategory._logger.Error(ex.Message); - SelectCategory._logger.Debug(ex.StackTrace); - } - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); - base.Dispose(disposing); - } - - private void InitializeComponent() - { - this.treeView1 = new TreeView(); - this._btCancel = new Button(); - this._btSelected = new Button(); - this._txtFrom = new TextBox(); - this.SuspendLayout(); - this.treeView1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - this.treeView1.Location = new Point(12, 12); - this.treeView1.Name = "treeView1"; - this.treeView1.Size = new Size(468, 495); - this.treeView1.TabIndex = 0; - this.treeView1.DoubleClick += new EventHandler(this._btSelected_Click); - this._btCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - this._btCancel.Location = new Point(405, 513); - this._btCancel.Name = "_btCancel"; - this._btCancel.Size = new Size(75, 23); - this._btCancel.TabIndex = 1; - this._btCancel.Text = "Отмена"; - this._btCancel.UseVisualStyleBackColor = true; - this._btCancel.Click += new EventHandler(this._btCancel_Click); - this._btSelected.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - this._btSelected.Location = new Point(324, 513); - this._btSelected.Name = "_btSelected"; - this._btSelected.Size = new Size(75, 23); - this._btSelected.TabIndex = 2; - this._btSelected.Text = "Выбрать"; - this._btSelected.UseVisualStyleBackColor = true; - this._btSelected.Click += new EventHandler(this._btSelected_Click); - this._txtFrom.Location = new Point(12, 513); - this._txtFrom.Name = "_txtFrom"; - this._txtFrom.Size = new Size(306, 20); - this._txtFrom.TabIndex = 3; - this._txtFrom.KeyDown += new KeyEventHandler(this._txtFrom_KeyDown); - this.AutoScaleDimensions = new SizeF(6f, 13f); - this.AutoScaleMode = AutoScaleMode.Font; - this.ClientSize = new Size(492, 548); - this.ControlBox = false; - this.Controls.Add((Control) this._txtFrom); - this.Controls.Add((Control) this._btSelected); - this.Controls.Add((Control) this._btCancel); - this.Controls.Add((Control) this.treeView1); - this.FormBorderStyle = FormBorderStyle.FixedToolWindow; - this.Name = "SelectCategory"; - this.StartPosition = FormStartPosition.CenterScreen; - this.Text = "Выбор категории"; - this.ResumeLayout(false); - this.PerformLayout(); - } - } -} diff --git a/Forms/SettingsForm.Designer.cs b/Forms/SettingsForm.Designer.cs deleted file mode 100644 index 21b7c29..0000000 --- a/Forms/SettingsForm.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Этот код создан программой. -// Исполняемая версия:4.0.30319.42000 -// -// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае -// повторной генерации кода. -// -//------------------------------------------------------------------------------ - -namespace TLO.local.Forms { - using System; - - - /// - /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - /// - // Этот класс создан автоматически классом StronglyTypedResourceBuilder - // с помощью такого средства, как ResGen или Visual Studio. - // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen - // с параметром /str или перестройте свой проект VS. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class SettingsForm { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal SettingsForm() { - } - - /// - /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TLO.local.Forms.SettingsForm", typeof(SettingsForm).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Перезаписывает свойство CurrentUICulture текущего потока для всех - /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/Info/Category.cs b/Info/Category.cs deleted file mode 100644 index 14be63c..0000000 --- a/Info/Category.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Category -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; - -namespace TLO.local -{ - internal class Category - { - public Category() - { - this.LastUpdateTopics = new DateTime(2000, 1, 1); - this.LastUpdateStatus = new DateTime(2000, 1, 1); - this.CountSeeders = 2; - this.CreateSubFolder = 2; - } - - public int CategoryID { get; set; } - - public int ParentID { get; set; } - - public int OrderID { get; set; } - - public string Name { get; set; } - - public string FullName { get; set; } - - public bool IsEnable { get; set; } - - public int CountSeeders { get; set; } - - public Guid TorrentClientUID { get; set; } - - public int CreateSubFolder { get; set; } - - public string Folder { get; set; } - - public string Label { get; set; } - - public bool IsSaveTorrentFiles { get; set; } - - public string FolderTorrentFile { get; set; } - - public bool IsSaveWebPage { get; set; } - - public string FolderSavePageForum { get; set; } - - public string ReportList { get; set; } - - public DateTime LastUpdateTopics { get; set; } - - public DateTime LastUpdateStatus { get; set; } - - public override string ToString() - { - return this.FullName; - } - } -} diff --git a/Info/TopicInfo.cs b/Info/TopicInfo.cs deleted file mode 100644 index e27cb8e..0000000 --- a/Info/TopicInfo.cs +++ /dev/null @@ -1,147 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.TopicInfo -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Web; - -namespace TLO.local -{ - internal class TopicInfo - { - protected static CultureInfo _cultureUsInfo = new CultureInfo("en-US"); - - public int TopicID { get; set; } - - public int Seeders { get; set; } - - public int Leechers { get; set; } - - public string Hash { get; set; } - - public int CategoryID { get; set; } - - public string Name - { - get - { - return HttpUtility.HtmlDecode(this.Name2); - } - } - - public string Name2 { get; set; } - - public string TorrentName { get; set; } - - public List Files { get; set; } - - public int Status { get; set; } - - public long Size { get; set; } - - public DateTime RegTime { get; set; } - - public Decimal? AvgSeeders { get; set; } - - public bool IsKeeper { get; set; } - - public bool IsKeep { get; set; } - - public bool IsDownload { get; set; } - - public bool IsBlackList { get; set; } - - public bool IsSelected { get; set; } - - public string Alternative - { - get - { - return ">>>>"; - } - } - - public bool? IsRun { get; set; } - - public bool IsPause { get; set; } - - public bool[] TorrentClientStatus { get; set; } - - public Decimal PercentComplite { get; set; } - - public bool Checked { get; set; } - - public static string sizeToString(long size) - { - if ((Decimal) size >= new Decimal(int.MinValue, 2, 0, false, (byte) 1)) - return Math.Round((Decimal) size / new Decimal(int.MinValue, 2, 0, false, (byte) 1), 2).ToString() + " GB"; - if ((Decimal) size >= new Decimal(10485760, 0, 0, false, (byte) 1)) - return Math.Round((Decimal) size / new Decimal(10485760, 0, 0, false, (byte) 1), 2).ToString() + " MB"; - if ((Decimal) size >= new Decimal(10240, 0, 0, false, (byte) 1)) - return Math.Round((Decimal) size / new Decimal(10240, 0, 0, false, (byte) 1), 2).ToString() + " KB"; - return Math.Round((Decimal) size, 2).ToString() + " B"; - } - - public string SizeToString - { - get - { - return TopicInfo.sizeToString(this.Size); - } - } - - public string StatusToString - { - get - { - switch (this.Status) - { - case 0: - return "*"; - case 1: - return "x"; - case 2: - return "√"; - case 3: - return "?"; - case 4: - return "!"; - case 5: - return "D"; - case 6: - return "©"; - case 7: - return "∑"; - case 8: - return "#"; - case 9: - return "%"; - case 10: - return "T"; - case 11: - return "∏"; - default: - return "-"; - } - } - } - - public string RegTimeToString - { - get - { - return this.RegTime.ToString("dd.MM.yyyy"); - } - } - - public int PosterID { get; set; } - - public bool IsPoster { get; set; } - - public int? KeeperCount { get; set; } - } -} diff --git a/Info/TorrentClientInfo.cs b/Info/TorrentClientInfo.cs deleted file mode 100644 index 1c04572..0000000 --- a/Info/TorrentClientInfo.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.TorrentClientInfo -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; - -namespace TLO.local -{ - internal class TorrentClientInfo - { - public TorrentClientInfo() - { - this.UID = Guid.NewGuid(); - this.Name = string.Empty; - this.Type = "uTorrent"; - this.ServerName = string.Empty; - this.ServerPort = 999; - this.UserName = string.Empty; - this.UserPassword = string.Empty; - this.LastReadHash = new DateTime(2000, 1, 1); - } - - public Guid UID { get; set; } - - public string Name { get; set; } - - public string Type { get; set; } - - public string ServerName { get; set; } - - public int ServerPort { get; set; } - - public string UserName { get; set; } - - public string UserPassword { get; set; } - - public DateTime LastReadHash { get; set; } - - public override string ToString() - { - return this.Name; - } - - public ITorrentClient Create() - { - ITorrentClient torrentClient = (ITorrentClient) null; - if (this.Type == "uTorrent") - torrentClient = (ITorrentClient) new uTorrentClient(this.ServerName, this.ServerPort, this.UserName, this.UserPassword); - else if (this.Type == "Transmission") - torrentClient = (ITorrentClient) new TransmissionClient(this.ServerName, this.ServerPort, this.UserName, this.UserPassword); - else if (this.Type == "Vuze (Vuze Web Remote)") - torrentClient = (ITorrentClient) new TransmissionClient(this.ServerName, this.ServerPort, this.UserName, this.UserPassword); - return torrentClient; - } - } -} diff --git a/Info/UserInfo.cs b/Info/UserInfo.cs deleted file mode 100644 index a0e036e..0000000 --- a/Info/UserInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.UserInfo -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -namespace TLO.local -{ - internal class UserInfo - { - public int UserID { get; set; } - - public string Name { get; set; } - } -} diff --git a/Logic.cs b/Logic.cs deleted file mode 100644 index 6de65fe..0000000 --- a/Logic.cs +++ /dev/null @@ -1,1165 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Logic -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Web; -using System.Windows.Forms; -using TLO.local.Forms; - -namespace TLO.local -{ - internal class Logic - { - private static Logger logger = LogManager.GetCurrentClassLogger(); - private static RuTrackerOrg _Current; - - public static RuTrackerOrg Current - { - get - { - if (Logic._Current == null) - Logic._Current = new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass); - return Logic._Current; - } - } - - public static void SendTorrentFileToTorrentClient(List topics, Category category) - { - TorrentClientInfo torrentClientInfo = ClientLocalDB.Current.GetTorrentClients().Where((Func) (x => x.UID == category.TorrentClientUID)).FirstOrDefault(); - if (torrentClientInfo == null) - return; - ITorrentClient torrentClient1 = torrentClientInfo.Create(); - if (torrentClient1 == null) - return; - if (string.IsNullOrWhiteSpace(category.Folder)) - throw new Exception("В разделе не указан каталог для загрузки"); - foreach (TopicInfo topic in topics) - { - if (topic.Status != 7 && topic.Status != 4) - { - int topicId; - if (category.CreateSubFolder != 0) - { - if (category.CreateSubFolder != 1) - throw new Exception("Не поддерживается указаный метод создания подкаталога"); - ITorrentClient torrentClient2 = torrentClient1; - string folder = category.Folder; - topicId = topic.TopicID; - string path2 = topicId.ToString(); - string dir = Path.Combine(folder, path2); - torrentClient2.SetDefaultFolder(dir); - } - byte[] buffer1 = new byte[0]; - if (buffer1.Length == 0) - buffer1 = Logic.Current.DownloadTorrentFile(topic.TopicID); - if (buffer1 == null) - break; - ITorrentClient torrentClient3 = torrentClient1; - string path; - if (category.CreateSubFolder != 1) - { - path = category.Folder; - } - else - { - string folder = category.Folder; - topicId = topic.TopicID; - string path2 = topicId.ToString(); - path = Path.Combine(folder, path2); - } - string filename = string.Format("[rutracker.org].t{0}.torrent", (object) topic.TopicID); - byte[] fdata = buffer1; - torrentClient3.SendTorrentFile(path, filename, fdata); - if (category.IsSaveTorrentFiles) - { - if (!Directory.Exists(category.FolderTorrentFile)) - Directory.CreateDirectory(category.FolderTorrentFile); - using (FileStream fileStream = File.Create(Path.Combine(category.FolderTorrentFile, string.Format("[rutracker.org].t{0}.torrent", (object) topic.TopicID)))) - fileStream.Write(buffer1, 0, ((IEnumerable) buffer1).Count()); - } - if (category.IsSaveWebPage) - { - Thread.Sleep(500); - byte[] buffer2 = Logic.Current.DownloadWebPages(string.Format("https://{1}/forum/viewtopic.php?t={0}", (object) topic.TopicID, Settings.Current.HostRuTrackerOrg)); - if (!Directory.Exists(category.FolderSavePageForum)) - Directory.CreateDirectory(category.FolderSavePageForum); - using (FileStream fileStream = File.Create(Path.Combine(category.FolderSavePageForum, string.Format("[rutracker.org].t{0}.html", (object) topic.TopicID)))) - fileStream.Write(buffer2, 0, ((IEnumerable) buffer2).Count()); - } - Thread.Sleep(500); - } - } - } - - public static void SendTorrentFileToTorrentClient(TopicInfo topic, Category category) - { - if (topic == null || category == null) - return; - Logic.SendTorrentFileToTorrentClient(new List() - { - topic - }, category); - } - - public static void SendReportToForum() - { - foreach (KeyValuePair, Tuple> report in ClientLocalDB.Current.GetReports(new int?())) - { - if (!string.IsNullOrWhiteSpace(report.Value.Item1)) - Logic.Current.SendReport(report.Value.Item1, report.Value.Item2); - } - } - - public static void SendReportToForum(ProgressBar pBar) - { - Dictionary, Tuple> reports = ClientLocalDB.Current.GetReports(new int?()); - pBar.Visible = true; - pBar.Minimum = 1; - pBar.Maximum = reports.Count; - pBar.Value = 1; - pBar.Step = 1; - foreach (KeyValuePair, Tuple> keyValuePair in reports) - { - if (!string.IsNullOrWhiteSpace(keyValuePair.Value.Item1)) - Logic.Current.SendReport(keyValuePair.Value.Item1, keyValuePair.Value.Item2); - pBar.PerformStep(); - } - } - - public static void LoadHashFromClients(List clients = null) - { - if (clients == null) - clients = ClientLocalDB.Current.GetTorrentClients(); - if (clients == null) - return; - foreach (TorrentClientInfo client in clients) - { - try - { - ITorrentClient torrentClient = client.Create(); - if (torrentClient != null) - ClientLocalDB.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); - } - catch - { - } - } - } - - public static void LoadHashFromClients(TorrentClientInfo client) - { - if (client == null) - return; - Logic.LoadHashFromClients(new List() - { - client - }); - } - - internal static void LoadHashFromClients(ProgressBar pBar) - { - List torrentClients = ClientLocalDB.Current.GetTorrentClients(); - pBar.Visible = true; - pBar.Minimum = 1; - pBar.Maximum = torrentClients.Count; - pBar.Value = 1; - pBar.Step = 1; - foreach (TorrentClientInfo torrentClientInfo in torrentClients) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient != null) - ClientLocalDB.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); - } - catch - { - } - pBar.PerformStep(); - } - } - - public static void LoadHashFromClients(Guid uid) - { - TorrentClientInfo client = ClientLocalDB.Current.GetTorrentClients().Where((Func) (x => x.UID == uid)).FirstOrDefault(); - if (client == null) - return; - Logic.LoadHashFromClients(client); - ClientLocalDB.Current.CreateReportByRootCategories(); - } - - public static void UpdateSeedersByCategories(List categories = null) - { - if (categories == null) - categories = ClientLocalDB.Current.GetCategoriesEnable(); - if (categories == null) - return; - foreach (Category category in categories) - ClientLocalDB.Current.SaveStatus(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID), true); - } - - public static void UpdateSeedersByCategory(Category category) - { - if (category == null) - return; - Logic.UpdateSeedersByCategories(new List() - { - category - }); - } - - public static void UpdateTopicsByCategories(List categories = null) - { - if (categories == null) - categories = ClientLocalDB.Current.GetCategoriesEnable(); - if (categories == null) - return; - foreach (Category category in categories) - ClientLocalDB.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(((IEnumerable) RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID)).Select((Func) (x => x[0])).Distinct().ToArray()), true); - } - - public static void UpdateTopicsByCategories(ProgressBar pBar) - { - List categoriesEnable = ClientLocalDB.Current.GetCategoriesEnable(); - pBar.Visible = true; - pBar.Minimum = 1; - pBar.Maximum = categoriesEnable.Count; - pBar.Value = 1; - pBar.Step = 1; - foreach (Category category in categoriesEnable) - { - ClientLocalDB.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(((IEnumerable) RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID)).Select((Func) (x => x[0])).Distinct().ToArray()), true); - pBar.PerformStep(); - } - } - - public static void UpdateTopicsByCategory(Category category) - { - if (category == null) - return; - Logic.UpdateTopicsByCategories(new List() - { - category - }); - } - - public static void bwDownloadTorrentFiles(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - Tuple, MainForm> tuple = e.Argument as Tuple, MainForm>; - List topicInfoList = tuple.Item1; - string folder = string.Empty; - if (topicInfoList == null || topicInfoList.Count == 0) - return; - tuple.Item2.Invoke((MethodInvoker)delegate - { - FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); - if (folderBrowserDialog.ShowDialog() != DialogResult.OK) - return; - folder = folderBrowserDialog.SelectedPath; - }); - if (string.IsNullOrWhiteSpace(folder)) - { - int num2; - tuple.Item2.Invoke((MethodInvoker)delegate { - num2 = (int)MessageBox.Show("Не указан каталог для сохранения торрент-файлов", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - }); - } - else - { - foreach (TopicInfo topicInfo in topicInfoList) - { - byte[] buffer = Logic.Current.DownloadTorrentFile(topicInfo.TopicID); - if (buffer != null) - { - using (FileStream fileStream = File.Create(Path.Combine(folder, string.Format("[rutracker.org].t{0}.torrent", (object) topicInfo.TopicID)))) - fileStream.Write(buffer, 0, ((IEnumerable) buffer).Count()); - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) topicInfoList.Count; - backgroundWorker.ReportProgress((int) num1); - } - } - } - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Произошла ошибка при скачивании торрент-файлов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwSendTorrentFileToTorrentClient(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - Tuple, Category> tuple = e.Argument as Tuple, Category>; - List topicInfoList = tuple.Item2; - Category category = tuple.Item3; - Logic.logger.Info("Запущена задача на скачивание и добавление торрент-файлов в торрент-клиент..."); - Logic.logger.Trace(string.Format("\tКол-во раздач для скачивания торрент-файлов: {0}", (object) topicInfoList.Count)); - TorrentClientInfo torrentClientInfo = ClientLocalDB.Current.GetTorrentClients().Where((Func) (x => x.UID == category.TorrentClientUID)).FirstOrDefault(); - IEnumerable source = torrentClientInfo.Create().GetAllTorrentHash().Where((Func) (x => !string.IsNullOrWhiteSpace(x.Hash))); - foreach (TopicInfo topicInfo1 in topicInfoList) - { - TopicInfo t = topicInfo1; - TopicInfo topicInfo2 = source.Where((Func) (x => x.Hash == t.Hash)).FirstOrDefault(); - if (topicInfo2 != null) - t.TorrentName = topicInfo2.TorrentName; - } - List list = source.Select((Func) (x => x.Hash)).ToList(); - if (torrentClientInfo == null) - { - Logic.logger.Warn("Не указан торрент-клиент в категории/подфоруме"); - } - else - { - string folder = category.Folder; - if (string.IsNullOrWhiteSpace(folder)) - tuple.Item1.Invoke((MethodInvoker)delegate - { - FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); - if (folderBrowserDialog.ShowDialog() != DialogResult.OK) - return; - folder = folderBrowserDialog.SelectedPath; - }); - if (string.IsNullOrWhiteSpace(folder)) - throw new Exception("Не указан каталог для загрузки"); - foreach (TopicInfo topicInfo in topicInfoList) - { - TopicInfo t = topicInfo; - try - { - if (t.Status != 7) - { - if (t.Status != 4) - { - string folder2 = string.Empty; - if (category.CreateSubFolder == 0) - folder2 = folder; - else if (category.CreateSubFolder == 1) - { - folder2 = Path.Combine(folder, t.TopicID.ToString()); - } - else - { - if (category.CreateSubFolder != 2) - throw new Exception("Не поддерживается указаный метод создания подкаталога"); - DialogResult result = DialogResult.None; - tuple.Item1.Invoke((MethodInvoker)delegate - { - FolderNameDialog folderNameDialog = new FolderNameDialog(); - folderNameDialog.SelectedPath = t.Name; - result = folderNameDialog.ShowDialog(); - folder2 = Path.Combine(folder, folderNameDialog.SelectedPath); - }); - if (result == DialogResult.Abort) - return; - if (result != DialogResult.Cancel) - { - if (result != DialogResult.OK) - throw new Exception("result != DialogResult.OK"); - } - else - continue; - } - if (!list.Contains(t.Hash)) - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient == null) - throw new ArgumentException("Не удалось создать подключение к торрент-клиенту \"" + torrentClientInfo.Name + "\""); - torrentClient.SetDefaultFolder(folder2); - byte[] numArray = Logic.Current.DownloadTorrentFile(t.TopicID); - if (numArray == null) - { - Logic.logger.Warn("Не удалось скачать торрент-файл для раздачи \"" + t.Name + "\". Статус раздачи: " + t.Status.ToString()); - continue; - } - torrentClient.SendTorrentFile(folder2, string.Format("[rutracker.org].t{0}.torrent", (object) t.TopicID), numArray); - torrentClient.SetLabel(t.Hash, string.IsNullOrWhiteSpace(category.Label) ? category.FullName : category.Label); - if (category.IsSaveTorrentFiles) - { - if (!Directory.Exists(category.FolderTorrentFile)) - Directory.CreateDirectory(category.FolderTorrentFile); - using (FileStream fileStream = File.Create(Path.Combine(category.FolderTorrentFile, string.Format("[rutracker.org].t{0}.torrent", (object) t.TopicID)))) - fileStream.Write(numArray, 0, ((IEnumerable) numArray).Count()); - } - } - if (category.IsSaveWebPage) - { - Thread.Sleep(500); - byte[] buffer = Logic.Current.DownloadWebPages(string.Format("https://{1}/forum/viewtopic.php?t={0}", (object) t.TopicID, Settings.Current.HostRuTrackerOrg)); - if (!Directory.Exists(category.FolderSavePageForum)) - Directory.CreateDirectory(category.FolderSavePageForum); - using (FileStream fileStream = File.Create(Path.Combine(category.FolderSavePageForum, string.Format("[rutracker.org].t{0}.html", (object) t.TopicID)))) - fileStream.Write(buffer, 0, ((IEnumerable) buffer).Count()); - } - if (!string.IsNullOrWhiteSpace(t.TorrentName)) - { - try - { - if (Directory.Exists(Path.Combine(category.Folder, t.TorrentName))) - { - if (!Directory.Exists(Path.Combine(category.Folder, t.TopicID.ToString()))) - Directory.CreateDirectory(Path.Combine(category.Folder, t.TopicID.ToString())); - Directory.Move(Path.Combine(category.Folder, t.TorrentName), Path.Combine(category.Folder, t.TopicID.ToString(), t.TorrentName)); - continue; - } - if (File.Exists(Path.Combine(category.Folder, t.TorrentName))) - { - if (!Directory.Exists(Path.Combine(category.Folder, t.TopicID.ToString()))) - Directory.CreateDirectory(Path.Combine(category.Folder, t.TopicID.ToString())); - File.Move(Path.Combine(category.Folder, t.TorrentName), Path.Combine(category.Folder, t.TopicID.ToString(), t.TorrentName)); - continue; - } - } - catch - { - } - } - } - else - continue; - } - else - continue; - } - catch (Exception ex) - { - Logic.logger.Warn("Не удалось скачать или добавить в торрент-клиент торрент-файл для раздачи \"" + t.Name + "\". Статус раздачи: " + t.Status.ToString() + "\t\t" + ex.Message); - } - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) topicInfoList.Count; - backgroundWorker.ReportProgress((int) num1); - } - Logic.logger.Info("Завершена задача на скачивание и добавление торрент-файлов в торрент-клиент."); - } - } - catch (Exception ex) - { - Logic.logger.Error("Произошла ошибка при скачивании и добавлении торрент-файлов в торрент-клиент: " + ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Поизошла ошибка при скачивании торрент-файлов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwSetLabels(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - Tuple, string> tuple = e.Argument as Tuple, string>; - List topicInfoList = tuple.Item2; - string label = tuple.Item3; - Logic.logger.Info("Запущена задача на установку пользовательских меток в торрент-клиент..."); - List torrentClients = ClientLocalDB.Current.GetTorrentClients(); - foreach (TorrentClientInfo torrentClientInfo in torrentClients) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - torrentClient.SetLabel((IEnumerable) torrentClient.GetAllTorrentHash().Join((IEnumerable) topicInfoList, (Func) (tc => tc.Hash), (Func) (tp => tp.Hash), (Func) ((tc, tp) => tp.Hash)).ToArray(), label); - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) torrentClients.Count(); - if (num1 <= new Decimal(100)) - backgroundWorker.ReportProgress((int) num1); - } - catch - { - } - } - backgroundWorker.ReportProgress(100); - } - catch (Exception ex) - { - Logic.logger.Error("Произошла ошибка при установке пользовательских меток в торрент-клиент: " + ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Произошла ошибка:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwUpdateCountSeedersByAllCategories(object sender, DoWorkEventArgs e) - { - Logic.logger.Info("Запущена задача на обновление информации о кол-ве сидов на раздачах..."); - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num); - try - { - Logic.logger.Trace("\t Очищаем историю о кол-ве сидов на раздаче..."); - ClientLocalDB.Current.ClearHistoryStatus(); - List categoriesEnable = ClientLocalDB.Current.GetCategoriesEnable(); - foreach (Category category in categoriesEnable) - { - Logic.logger.Trace("\t " + category.Name + "..."); - try - { - ClientLocalDB.Current.SaveStatus(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID), true); - } - catch (Exception ex) - { - Logic.logger.Warn("Не удалось обновить кол-во сидов по разделу \"" + category.Name + "\""); - Logic.logger.Debug(ex); - } - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) categoriesEnable.Count; - backgroundWorker.ReportProgress((int) num); - } - if (Settings.Current.IsUpdateStatistics) - { - Logic.logger.Trace("\t Обновление статистики..."); - ClientLocalDB.Current.UpdateStatistics(); - } - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - } - Logic.logger.Info("Завершена задача по обновлению информации о кол-ве сидов на раздачах."); - } - - public static void bwUpdateHashFromAllTorrentClients(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - ClientLocalDB.Current.ResetFlagsTopicDownloads(); - List torrentClients = ClientLocalDB.Current.GetTorrentClients(); - foreach (TorrentClientInfo torrentClientInfo in torrentClients) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient != null) - ClientLocalDB.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); - } - catch (Exception ex) - { - Logic.logger.Warn("Не удалось загрузить список статусов раздач из torrent-клиента \"" + torrentClientInfo.Name + "\": \"" + ex.Message + "\". Возможно клиент не запущен или нет доступа."); - Logic.logger.Debug(ex); - } - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) torrentClients.Count; - backgroundWorker.ReportProgress((int) num1); - } - Logic.CreateReports(); - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Поизошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwUpdateHashFromTorrentClientsByCategoryUID(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - Category category = e.Argument as Category; - if (category == null) - return; - Logic.logger.Info("Обновление списка хранимого из торрент-клиента (по разделу)..."); - List list = ClientLocalDB.Current.GetTorrentClients().Where((Func) (x => x.UID == category.TorrentClientUID)).ToList(); - foreach (TorrentClientInfo torrentClientInfo in list) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient != null) - ClientLocalDB.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); - } - catch (Exception ex) - { - Logic.logger.Warn("Не удалось загрузить список статусов раздач из torrent-клиента \"" + torrentClientInfo.Name + "\": \"" + ex.Message + "\". Возможно клиент не запущен или нет доступа."); - Logic.logger.Debug(ex); - } - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) list.Count; - backgroundWorker.ReportProgress((int) num1); - } - Logic.CreateReports(); - Logic.logger.Info("Завершена задача по обновлению списка хранимого из торрент-клиента (по разделу)."); - } - catch (Exception ex) - { - Logic.logger.Error("Произошла ошибка при обновлении списка хранимого из торрент-клиента: " + ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwUpdateTopicsByCategory(object sender, DoWorkEventArgs e) - { - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Category category = e.Argument as Category; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - int[] array = ((IEnumerable) RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID)).Select((Func) (x => x[0])).Distinct().ToArray(); - List[] intListArray = new List[array.Length % 100 == 0 ? array.Length / 100 : array.Length / 100 + 1]; - for (int index1 = 0; index1 < array.Length; ++index1) - { - int index2 = index1 / 100; - if (intListArray[index2] == null) - intListArray[index2] = new List(); - intListArray[index2].Add(array[index1]); - } - foreach (List intList in intListArray) - { - ClientLocalDB.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(intList.ToArray()), true); - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) intListArray.Length; - backgroundWorker.ReportProgress((int) num1); - } - ClientLocalDB.Current.SaveUsers(RuTrackerOrg.Current.GetUsers(ClientLocalDB.Current.GetNoUsers())); - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - } - - public static void bwUpdateTopicsByCategories(object sender, DoWorkEventArgs e) - { - Logic.logger.Info("Запущена задача по обновлению топиков..."); - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - List categoryList = e.Argument as List; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - foreach (Category category in categoryList) - { - Logic.logger.Trace("\t Обрабатывается форум \"" + category.Name + "\"..."); - try - { - int[] array = ((IEnumerable) RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID)).Select((Func) (x => x[0])).Distinct().ToArray(); - List[] intListArray = new List[array.Length % 100 == 0 ? array.Length / 100 : array.Length / 100 + 1]; - for (int index1 = 0; index1 < array.Length; ++index1) - { - int index2 = index1 / 100; - if (intListArray[index2] == null) - intListArray[index2] = new List(); - intListArray[index2].Add(array[index1]); - } - ClientLocalDB.Current.DeleteTopicsByCategoryId(category.CategoryID); - foreach (List intList in intListArray) - { - ClientLocalDB.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(intList.ToArray()), true); - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) (categoryList.Count * intListArray.Length); - backgroundWorker.ReportProgress((int) num1); - } - } - catch (Exception ex) - { - Logic.logger.Error("Ошибка при обновлении топиков: " + ex.Message); - Logic.logger.Debug(ex); - } - ClientLocalDB.Current.SaveUsers(RuTrackerOrg.Current.GetUsers(ClientLocalDB.Current.GetNoUsers())); - } - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - Logic.logger.Info("Завершена задача по обновлению топиков."); - } - - public static void bwUpdateKeepersByAllCategories(object sender, DoWorkEventArgs e) - { - Logic.logger.Info("Запущена задача по обновлению информации о хранителях..."); - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num1); - try - { - ClientLocalDB.Current.ClearKeepers(); - int[] categories = ClientLocalDB.Current.GetCategoriesEnable().Select(x => x.CategoryID).OrderBy(x => x).ToArray(); - var array = ClientLocalDB.Current.GetReports(new int?()).Where(x => - { - if (x.Key.Item2 == 0 && x.Key.Item1 != 0 && !string.IsNullOrWhiteSpace(x.Value.Item1)) - return categories.Any((Func) (z => z == x.Key.Item1)); - return false; - }).Select(x => - { - string[] strArray = x.Value.Item1.Split('='); - if (strArray.Length == 3) - return new - { - TopicID = int.Parse(strArray[2]), - CategoryID = x.Key.Item1 - }; - if (strArray.Length == 2) - return new - { - TopicID = int.Parse(strArray[1]), - CategoryID = x.Key.Item1 - }; - return new - { - TopicID = 0, - CategoryID = x.Key.Item1 - }; - }).Where(x => (uint) x.TopicID > 0U).OrderBy(x => x.CategoryID).ToArray(); - RuTrackerOrg ruTrackerOrg = new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass); - foreach (var data in array) - { - Logic.logger.Trace("\t" + (object) data.CategoryID); - ClientLocalDB.Current.SaveKeepOtherKeepers(ruTrackerOrg.GetKeeps(data.TopicID, data.CategoryID)); - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) array.Count(); - backgroundWorker.ReportProgress((int) num1); - } - ClientLocalDB.Current.CreateReportByRootCategories(); - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num2 = (int) MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - Logic.logger.Info("Завершена задача по обновлению информации о хранителях."); - } - - public static void bwRuningAndStopingDistributions(object sender, DoWorkEventArgs e) - { - Logic.logger.Info("Запущена задача по запуску/остановке раздач в торрент-клиентах..."); - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - object obj = e.Argument; - Decimal num = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num); - Dictionary countSeedersBycategories = new Dictionary(); - try - { - IEnumerable inner = ClientLocalDB.Current.GetTopicsByCategory(-1).Where((Func) (x => !x.IsBlackList)); - foreach (Category category in ClientLocalDB.Current.GetCategoriesEnable()) - { - if (!countSeedersBycategories.ContainsKey(category.CategoryID)) - countSeedersBycategories.Add(category.CategoryID, category.CountSeeders); - } - ClientLocalDB.Current.ResetFlagsTopicDownloads(); - List torrentClients = ClientLocalDB.Current.GetTorrentClients(); - foreach (TorrentClientInfo torrentClientInfo in torrentClients) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient != null) - { - List allTorrentHash = torrentClient.GetAllTorrentHash(); - Logic.logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + "\": " + (object) allTorrentHash.Count); - ClientLocalDB.Current.SetTorrentClientHash(allTorrentHash); - var list = allTorrentHash.Join(inner, (Func) (c => c.Hash), (Func) (a => a.Hash), (c, a) => new - { - c = c, - a = a - }).Where(_param1 => _param1.c.IsRun.HasValue).Select(_param1 => new - { - Hash = _param1.a.Hash, - IsRun = _param1.c.IsRun.Value, - IsPause = _param1.c.IsPause, - Seeders = _param1.a.Seeders, - MaxSeeders = countSeedersBycategories.ContainsKey(_param1.a.CategoryID) ? new int?(countSeedersBycategories[_param1.a.CategoryID]) : new int?() - }).ToList(); - string[] array1 = list.Where(x => - { - if (x.IsRun && x.MaxSeeders.HasValue) - return x.Seeders > x.MaxSeeders.Value + 1; - return false; - }).Select(x => x.Hash).ToArray(); - Logic.logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + "\" которые требуется остановить: " + (object) array1.Length + ". Останавливаем..."); - List[] stringListArray1 = new List[array1.Length / 50 + (array1.Length % 50 != 0 ? 1 : 0)]; - for (int index1 = 0; index1 < array1.Length; ++index1) - { - int index2 = index1 / 50; - if (stringListArray1[index2] == null) - stringListArray1[index2] = new List(); - stringListArray1[index2].Add(array1[index1]); - } - if (stringListArray1.Length == 0) - { - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) (2 * torrentClients.Count); - backgroundWorker.ReportProgress((int) num); - } - foreach (List stringList in stringListArray1) - { - if (stringList != null) - torrentClient.DistributionStop((IEnumerable) stringList); - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) (2 * torrentClients.Count * stringListArray1.Length); - backgroundWorker.ReportProgress((int) num); - } - string[] array2 = list.Where(x => - { - if ((!x.IsRun || x.IsPause) && x.MaxSeeders.HasValue) - return x.Seeders <= x.MaxSeeders.Value; - return false; - }).Select(x => x.Hash).ToArray(); - List[] stringListArray2 = new List[array2.Length / 50 + (array2.Length % 50 != 0 ? 1 : 0)]; - Logic.logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + "\" которые требуется запустить: " + (object) array2.Length + ". Запускаем..."); - for (int index1 = 0; index1 < array2.Length; ++index1) - { - int index2 = index1 / 50; - if (stringListArray2[index2] == null) - stringListArray2[index2] = new List(); - stringListArray2[index2].Add(array2[index1]); - } - if (stringListArray2.Length == 0) - { - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) (2 * torrentClients.Count); - backgroundWorker.ReportProgress((int) num); - } - foreach (List stringList in stringListArray2) - { - if (stringList != null) - torrentClient.DistributionStart((IEnumerable) stringList); - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) (2 * torrentClients.Count * stringListArray2.Length); - backgroundWorker.ReportProgress((int) num); - } - } - else - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) torrentClients.Count; - backgroundWorker.ReportProgress((int) num); - } - catch (Exception ex) - { - Logic.logger.Warn("Не удалось запустить/остановить раздачи на клиенте \"" + torrentClientInfo.Name + "\": " + ex.Message); - Logic.logger.Debug(ex); - num += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) torrentClients.Count; - } - backgroundWorker.ReportProgress((int) num); - } - Logic.logger.Info("Строим отчеты о хранимом..."); - Logic.CreateReports(); - Logic.logger.Info("Отчеты о хранимом построены."); - } - catch (Exception ex) - { - Logic.logger.Warn("Произошла критическая ошибка при запуске/остановке раздач"); - Logic.logger.Debug(ex); - } - Logic.logger.Info("Завершена задача по запуску/остановке раздач в торрент-клиентах."); - Logic.logger.Debug(string.Format("Размер ОЗУ 1: {0}", (object) GC.GetTotalMemory(false))); - GC.Collect(2); - Logic.logger.Debug(string.Format("Размер ОЗУ 2: {0}", (object) GC.GetTotalMemory(false))); - } - - public static void bwCreateReportsTorrentClients(object sender, DoWorkEventArgs e) - { - List torrentClients = ClientLocalDB.Current.GetTorrentClients(); - IEnumerable inner = ClientLocalDB.Current.GetTopicsByCategory(-1).Where((Func) (x => !x.IsBlackList)); - Logic.logger.Info("Строим отчет о статистике в торрент-клиенте..."); - StringBuilder stringBuilder = new StringBuilder(); - Dictionary dictionary = ClientLocalDB.Current.GetCategories().ToDictionary((Func) (x => x.CategoryID), (Func) (x => x)); - int num1 = Math.Max(dictionary.Count == 0 ? 20 : dictionary.Values.Max((Func) (x => x.FullName.Length)), torrentClients.Count == 0 ? 20 : torrentClients.Max((Func) (x => x.Name.Length))); - string empty = string.Empty; - for (int index = 0; index < num1; ++index) - empty += "*"; - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Decimal num2 = new Decimal(0, 0, 0, false, (byte) 1); - backgroundWorker.ReportProgress((int) num2); - foreach (TorrentClientInfo torrentClientInfo in torrentClients) - { - Logic.logger.Debug("\t" + torrentClientInfo.Name + "..."); - try - { - stringBuilder.AppendLine(empty); - stringBuilder.AppendFormat("*\t{0}\r\n", (object) torrentClientInfo.Name); - stringBuilder.AppendLine(empty); - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient != null) - { - var array1 = torrentClient.GetAllTorrentHash().GroupJoin(inner, (Func) (t => t.Hash), (Func) (b => b.Hash), (t, bt) => new - { - t = t, - bt = bt - }).SelectMany(_param1 => _param1.bt.DefaultIfEmpty(), (_param1, b) => - { - int num3 = b != null ? b.CategoryID : -1; - long size = _param1.t.Size; - bool? isRun = _param1.t.IsRun; - int num4; - if (!isRun.HasValue) - { - num4 = -1; - } - else - { - isRun = _param1.t.IsRun; - num4 = isRun.Value ? 1 : 0; - } - int num5 = _param1.t.IsPause ? 1 : 0; - int num6 = b == null ? -1 : b.Seeders; - return new - { - CategoryID = num3, - Size = size, - IsRun = num4, - IsPause = num5 != 0, - Seeders = num6 - }; - }).GroupBy(x => new - { - CategoryID = x.CategoryID, - IsRun = x.IsRun, - IsPause = x.IsPause, - Seeders = x.Seeders - }).Select(x => new - { - CategoryID = x.Key.CategoryID, - IsRun = x.Key.IsRun, - IsPause = x.Key.IsPause, - Size = x.Sum(y => y.Size), - Count = x.Count(), - Seeders = x.Key.Seeders - }).ToArray(); - stringBuilder.AppendFormat("\tВсего:\t\t{0,6} шт. ({1})\r\n", (object) array1.Sum(x => x.Count), (object) TopicInfo.sizeToString(array1.Sum(x => x.Size))); - stringBuilder.AppendFormat("\tРаздаются:\t{0,6} шт. ({1})\r\n", (object) array1.Where(x => x.IsRun == 1).Sum(x => x.Count), (object) TopicInfo.sizeToString(array1.Where(x => x.IsRun == 1).Sum(x => x.Size))); - stringBuilder.AppendFormat("\tОстановлены:\t{0,6} шт. ({1})\r\n", (object) array1.Where(x => x.IsRun == 0).Sum(x => x.Count), (object) TopicInfo.sizeToString(array1.Where(x => x.IsRun == 0).Sum(x => x.Size))); - stringBuilder.AppendFormat("\tПрочие:\t\t{0,6} шт. ({1})\r\n", (object) array1.Where(x => x.IsRun == -1).Sum(x => x.Count), (object) TopicInfo.sizeToString(array1.Where(x => x.IsRun == -1).Sum(x => x.Size))); - stringBuilder.AppendFormat("\tНеизвестные:\t{0,6} шт. ({1})\r\n", (object) array1.Where(x => x.CategoryID == -1).Sum(x => x.Count), (object) TopicInfo.sizeToString(array1.Where(x => x.CategoryID == -1).Sum(x => x.Size))); - stringBuilder.AppendLine(); - stringBuilder.AppendFormat("\tПо кол-ву сидов:\r\n"); - foreach (var data in array1.GroupBy(x => x.Seeders).Select(x => new - { - Seeders = x.Key, - Count = x.Sum(z => z.Count), - Size = x.Sum(z => z.Size) - }).OrderBy(x => x.Seeders)) - stringBuilder.AppendFormat("\t{2}:\t\t{0,5} шт. ({1})\r\n", (object) data.Count, (object) TopicInfo.sizeToString(data.Size), (object) data.Seeders); - stringBuilder.AppendLine(); - foreach (int num3 in array1.Select(x => x.CategoryID).Distinct().OrderBy((Func) (x => x)).ToArray()) - { - int c = num3; - var array2 = array1.Where(x => x.CategoryID == c).ToArray(); - string str = "Неизвестные"; - if (dictionary.ContainsKey(c)) - str = dictionary[c].FullName; - stringBuilder.AppendFormat("{0}:\r\n", (object) str); - stringBuilder.AppendFormat("\tВсего:\t\t{0,5} шт. ({1})\r\n", (object) array2.Sum(x => x.Count), (object) TopicInfo.sizeToString(array2.Sum(x => x.Size))); - stringBuilder.AppendFormat("\tРаздаются:\t{0,5} шт. ({1})\r\n", (object) array2.Where(x => x.IsRun == 1).Sum(x => x.Count), (object) TopicInfo.sizeToString(array2.Where(x => x.IsRun == 1).Sum(x => x.Size))); - stringBuilder.AppendFormat("\tОстановлены:\t{0,5} шт. ({1})\r\n", (object) array2.Where(x => x.IsRun == 0).Sum(x => x.Count), (object) TopicInfo.sizeToString(array2.Where(x => x.IsRun == 0).Sum(x => x.Size))); - stringBuilder.AppendFormat("\tПрочие:\t\t{0,5} шт. ({1})\r\n", (object) array2.Where(x => x.IsRun == -1).Sum(x => x.Count), (object) TopicInfo.sizeToString(array2.Where(x => x.IsRun == -1).Sum(x => x.Size))); - } - stringBuilder.AppendLine(); - } - } - catch (Exception ex) - { - stringBuilder.AppendFormat("Ошибка: {0}\r\n\r\n\r\n", (object) ex.Message); - } - stringBuilder.AppendLine(); - num2 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) torrentClients.Count(); - if (num2 <= new Decimal(100)) - backgroundWorker.ReportProgress((int) num2); - } - Dictionary> reports = new Dictionary>(); - reports.Add(0, new Dictionary()); - reports[0].Add(1, stringBuilder.ToString()); - try - { - ClientLocalDB.Current.SaveReports(reports); - Logic.logger.Info("Отчет о статистике в торрент-клиенте построен."); - } - catch (Exception ex) - { - Logic.logger.Error("Произошла ошибка при сохранении отчета в базу данных: " + ex.Message); - Logic.logger.Trace(ex.StackTrace); - } - } - - public static void bwSendReports(object sender, DoWorkEventArgs e) - { - Logic.logger.Info("Запущена задача на отправку отчетов на форум...."); - Decimal num1 = new Decimal(0, 0, 0, false, (byte) 1); - BackgroundWorker backgroundWorker = sender as BackgroundWorker; - Tuple[] array = ClientLocalDB.Current.GetReports(new int?()).Where, Tuple>>((Func, Tuple>, bool>) (x => !string.IsNullOrWhiteSpace(x.Value.Item1))).OrderBy, Tuple>, int>((Func, Tuple>, int>) (x => x.Key.Item1)).Select, Tuple>, Tuple>((Func, Tuple>, Tuple>) (x => x.Value)).Where>((Func, bool>) (x => x.Item1.Split('=').Length == 3)).ToArray>(); - if (((IEnumerable>) array).Where>((Func, bool>) (x => !string.IsNullOrWhiteSpace(x.Item1))).Count>() == 0) - { - int num2 = (int) MessageBox.Show("Нет ни одного отчета c указанным URL для отправки на форум"); - } - else - { - foreach (Tuple tuple in ((IEnumerable>) array).Where>((Func, bool>) (x => !string.IsNullOrWhiteSpace(x.Item1)))) - { - Logic.logger.Info(tuple.Item1); - try - { - Logic.Current.SendReport(tuple.Item1, tuple.Item2); - } - catch (Exception ex) - { - Logic.logger.Error(ex.Message); - Logic.logger.Debug(ex); - int num3 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); - } - num1 += new Decimal(1000, 0, 0, false, (byte) 1) / (Decimal) array.Length; - backgroundWorker.ReportProgress((int) num1); - } - Logic.logger.Info("Завершена задача на отправку отчетов на форум."); - } - } - - public static void CreateReports() - { - ClientLocalDB.Current.ClearReports(); - List categoriesEnable = ClientLocalDB.Current.GetCategoriesEnable(); - Dictionary, Tuple> reports1 = ClientLocalDB.Current.GetReports(new int?()); - Dictionary> reports2 = new Dictionary>(); - Tuple[] array1 = ClientLocalDB.Current.GetStatisticsByAllUsers().Where>((Func, bool>) (x => !string.IsNullOrWhiteSpace(x.Item2))).ToArray>(); - StringBuilder stringBuilder1 = new StringBuilder(); - Tuple[] array2 = ((IEnumerable>) array1).Where>((Func, bool>) (x => x.Item2 == Settings.Current.KeeperName)).ToArray>(); - int[] catId = categoriesEnable.Select((Func) (x => x.CategoryID)).ToArray(); - stringBuilder1.Clear(); - stringBuilder1.AppendFormat("Актуально на: {0}\r\n\r\n", (object) DateTime.Now.ToString("dd.MM.yyyy")); - stringBuilder1.AppendFormat("Общее количество хранимых раздач: {0} шт.\r\n", (object) ((IEnumerable>) array2).Where>((Func, bool>) (x => ((IEnumerable) catId).Contains(x.Item1))).Sum>((Func, int>) (x => x.Item3))); - stringBuilder1.AppendFormat("Общий вес хранимых раздач: {0} Gb\r\n", (object) ((IEnumerable>) array2).Where>((Func, bool>) (x => ((IEnumerable) catId).Contains(x.Item1))).Sum>((Func, Decimal>) (x => x.Item4)).ToString("0.00")); - stringBuilder1.AppendLine("[hr]"); - foreach (Category category1 in (IEnumerable) categoriesEnable.OrderBy((Func) (x => x.FullName))) - { - Category category = category1; - Tuple tuple = ((IEnumerable>) array2).Where>((Func, bool>) (x => x.Item1 == category.CategoryID)).FirstOrDefault>() ?? new Tuple(category.CategoryID, "<->", 0, Decimal.Zero); - string empty1 = string.Empty; - if (reports1.ContainsKey(new Tuple(tuple.Item1, 1))) - { - string str = reports1[new Tuple(tuple.Item1, 1)].Item1; - string empty2; - if (!string.IsNullOrWhiteSpace(str)) - { - if (str.Split('=').Length > 2) - { - empty2 = str.Split('=')[2]; - goto label_7; - } - } - empty2 = string.Empty; -label_7: - stringBuilder1.AppendFormat("{0}{1}{2} - {3} шт. ({4:0.00} GB)\r\n", string.IsNullOrWhiteSpace(empty2) ? (object) "" : (object) string.Format("[url=https://rutracker.org/forum/viewtopic.php?p={0}#{0}]", (object) empty2), (object) category.FullName, string.IsNullOrWhiteSpace(empty2) ? (object) "" : (object) "[/url]", (object) tuple.Item3, (object) tuple.Item4); - } - } - reports2.Add(0, new Dictionary()); - reports2[0].Add(0, stringBuilder1.ToString()); - ClientLocalDB.Current.SaveReports(reports2); - reports2.Clear(); - foreach (Category category1 in categoriesEnable) - { - Category category = category1; - stringBuilder1.Clear(); - IEnumerable> source = ((IEnumerable>) array1).Where>((Func, bool>) (x => - { - if (x.Item1 == category.CategoryID && x.Item3 > 0) - return x.Item2 != "All"; - return false; - })); - Tuple tuple1 = ((IEnumerable>) array1).Where>((Func, bool>) (x => - { - if (x.Item1 == category.CategoryID) - return x.Item2 == "All"; - return false; - })).FirstOrDefault>(); - if (source != null && source.Count>() != 0 && tuple1 != null) - { - stringBuilder1.AppendFormat("[url=viewforum.php?f={0}][color=darkgreen][b]{1}[/b][/color][/url] | [url=tracker.php?f={0}&tm=-1&o=10&s=1][color=darkgreen][b]Проверка сидов[/b][/color][/url]\r\n\r\n", (object) category.CategoryID, (object) category.Name); - stringBuilder1.AppendFormat("[b]Актуально на:[/b] {0}\r\n\r\n", (object) DateTime.Now.ToString("dd.MM.yyyy")); - stringBuilder1.AppendFormat("[b]Общее количество раздач в подразделе:[/b] {0} шт.\r\n", (object) tuple1.Item3); - stringBuilder1.AppendFormat("[b]Общий размер раздач в подразделе:[/b] {0:0.00} GB.\r\n", (object) tuple1.Item4); - stringBuilder1.AppendFormat("[b]Количество хранителей:[/b] {0}\r\n", (object) source.Count>()); - stringBuilder1.AppendFormat("[b]Общее количество хранимых раздач:[/b] {0} шт.\r\n", (object) source.Sum>((Func, int>) (x => x.Item3))); - stringBuilder1.AppendFormat("[b]Общий вес хранимых раздач:[/b] {0:0.00} GB.\r\n", (object) source.Sum>((Func, Decimal>) (x => x.Item4))); - stringBuilder1.AppendLine("[hr]"); - int num = 0; - foreach (Tuple tuple2 in (IEnumerable>) source.OrderBy, string>((Func, string>) (x => x.Item2))) - { - ++num; - stringBuilder1.AppendFormat("[b]Хранитель {0}:[/b] [url=profile.php?mode=viewprofile&u={4}][color=darkgreen][b]{1}[/b][/color][/url] - {2} шт. ({3:0.00} GB)\r\n", (object) num, (object) tuple2.Item2.Replace("", ""), (object) tuple2.Item3, (object) tuple2.Item4, (object) HttpUtility.UrlEncode(tuple2.Item2.Replace("", "").Trim())); - } - reports2.Add(category.CategoryID, new Dictionary()); - reports2[category.CategoryID].Add(0, stringBuilder1.ToString()); - } - } - ClientLocalDB.Current.SaveReports(reports2); - reports2.Clear(); - string format1 = Settings.Current.ReportTop1.Replace("%%CreateDate%%", "{0}").Replace("%%CountTopics%%", "{1}").Replace("%%SizeTopics%%", "{2}") + "\r\n"; - string format2 = Settings.Current.ReportTop2.Replace("%%CreateDate%%", "{0}").Replace("%%CountTopics%%", "{1}").Replace("%%SizeTopics%%", "{2}").Replace("%%NumberTopicsFirst%%", "{3}").Replace("%%NumberTopicsLast%%", "{4}").Replace("%%ReportLines%%", "{5}").Replace("%%Top1%%", "{6}") + "\r\n"; - string format3 = Settings.Current.ReportLine.Replace("%%ID%%", "{0}").Replace("%%Name%%", "{1}").Replace("%%Size%%", "{2}").Replace("%%Status%%", "{3}").Replace("%%CountSeeders%%", "{4}").Replace("%%Date%%", "{5}"); - int num1 = 115000; - StringBuilder stringBuilder2 = new StringBuilder(); - StringBuilder stringBuilder3 = new StringBuilder(); - foreach (Category category in categoriesEnable) - { - int num2 = 0; - int num3 = 0; - int num4 = 1; - int key = 0; - stringBuilder2.Clear(); - stringBuilder3.Clear(); - TopicInfo[] array3 = ClientLocalDB.Current.GetTopicsByCategory(category.CategoryID).Where((Func) (x => - { - if (x.IsKeep && (x.Seeders <= Settings.Current.CountSeedersReport || Settings.Current.CountSeedersReport == -1)) - return !x.IsBlackList; - return false; - })).OrderBy((Func) (x => x.Name2)).ToArray(); - if (array3.Length != 0) - { - reports2.Add(category.CategoryID, new Dictionary()); - Dictionary dictionary = reports2[category.CategoryID]; - string str = string.Format(format1, (object) DateTime.Now.ToString("dd.MM.yyyy"), (object) array3.Length, (object) TopicInfo.sizeToString(((IEnumerable) array3).Sum((Func) (x => x.Size)))); - foreach (TopicInfo topicInfo in array3) - { - stringBuilder3.AppendLine(string.Format(format3, (object) topicInfo.TopicID, (object) topicInfo.Name2, (object) topicInfo.SizeToString, (object) topicInfo.StatusToString, (object) topicInfo.Seeders, (object) topicInfo.RegTimeToString)); - ++num2; - ++num3; - if (num2 % 10 == 0 || array3.Length <= num2) - { - if (array3.Length == num2) - { - if (num3 == 0) - stringBuilder2.AppendFormat("[*={0}{1}", (object) num4, (object) stringBuilder3.ToString().Substring(2)); - else - stringBuilder2.AppendLine(stringBuilder3.ToString()); - } - if (num1 <= stringBuilder2.Length + stringBuilder3.Length + str.Length || array3.Length <= num2) - { - ++key; - int num5 = num2 < array3.Length ? num2 - 10 : num2; - dictionary.Add(key, string.Format(format2, (object) DateTime.Now.ToString("dd.MM.yyyy"), (object) array3.Length, (object) TopicInfo.sizeToString(((IEnumerable) array3).Sum((Func) (x => x.Size))), (object) num4, (object) num5, (object) stringBuilder2.ToString(), (object) str) + Settings.Current.ReportBottom); - stringBuilder2.Clear(); - num3 = 0; - num4 = num5 + 1; - str = string.Empty; - } - if (num3 == 0) - stringBuilder2.AppendFormat("[*={0}{1}\r\n", (object) num4, (object) stringBuilder3.ToString().Substring(2)); - else - stringBuilder2.AppendLine(stringBuilder3.ToString()); - stringBuilder3.Clear(); - } - } - } - } - ClientLocalDB.Current.SaveReports(reports2); - } - } -} diff --git a/Program.cs b/Program.cs deleted file mode 100644 index 14e45bc..0000000 --- a/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Program -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System; -using System.Windows.Forms; - -namespace TLO.local -{ - internal static class Program - { - [STAThread] - private static void Main() - { - try - { - Settings current = Settings.Current; - ClientLocalDB.Current.GetCategoriesEnable(); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run((Form) new MainForm()); - } - catch (Exception ex) - { - int num = (int) MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); - } - } - } -} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs deleted file mode 100644 index f9b2b46..0000000 --- a/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("TLO.local")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TLO.local")] -[assembly: AssemblyCopyright("Copyright © 2014-2019")] -[assembly: AssemblyTrademark("")] -[assembly: ComVisible(false)] -[assembly: Guid("9b0990b0-a1dd-44ae-ab0c-0510e8769860")] -[assembly: AssemblyFileVersion("2.7.0.3")] -[assembly: AssemblyVersion("2.7.0.3")] diff --git a/Properties/Resources.cs b/Properties/Resources.cs deleted file mode 100644 index 2e03194..0000000 --- a/Properties/Resources.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Properties.Resources -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System.CodeDom.Compiler; -using System.ComponentModel; -using System.Diagnostics; -using System.Globalization; -using System.Resources; -using System.Runtime.CompilerServices; - -namespace TLO.local.Properties -{ - [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [DebuggerNonUserCode] - [CompilerGenerated] - internal class Resources - { - private static ResourceManager resourceMan; - private static CultureInfo resourceCulture; - - internal Resources() - { - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - internal static ResourceManager ResourceManager - { - get - { - if (TLO.local.Properties.Resources.resourceMan == null) - TLO.local.Properties.Resources.resourceMan = new ResourceManager("TLO.local.Properties.Resources", typeof (TLO.local.Properties.Resources).Assembly); - return TLO.local.Properties.Resources.resourceMan; - } - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - internal static CultureInfo Culture - { - get - { - return TLO.local.Properties.Resources.resourceCulture; - } - set - { - TLO.local.Properties.Resources.resourceCulture = value; - } - } - } -} diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs deleted file mode 100644 index 93380fe..0000000 --- a/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Этот код создан программой. -// Исполняемая версия:4.0.30319.42000 -// -// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае -// повторной генерации кода. -// -//------------------------------------------------------------------------------ - -namespace TLO.local.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/Properties/Settings.cs b/Properties/Settings.cs deleted file mode 100644 index 3099d38..0000000 --- a/Properties/Settings.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Properties.Settings -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using System.CodeDom.Compiler; -using System.Configuration; -using System.Runtime.CompilerServices; - -namespace TLO.local.Properties -{ - [CompilerGenerated] - [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed class Settings : ApplicationSettingsBase - { - private static Settings defaultInstance = (Settings) SettingsBase.Synchronized((SettingsBase) new Settings()); - - public static Settings Default - { - get - { - return Settings.defaultInstance; - } - } - } -} diff --git a/Properties/Settings.settings b/Properties/Settings.settings deleted file mode 100644 index 049245f..0000000 --- a/Properties/Settings.settings +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Settings.cs b/Settings.cs deleted file mode 100644 index 8b9a3ea..0000000 --- a/Settings.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.Settings -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - -using NLog; -using NLog.Config; -using NLog.Layouts; -using NLog.Targets; -using System; -using System.IO; -using System.Reflection; -using System.Text; -using System.Xml.Serialization; - -namespace TLO.local -{ - public class Settings - { - private static Logger _logger = LogManager.GetLogger("Settings"); - private DateTime _LastWriteTime; - private static Settings _data; - - public string FileSettings - { - get - { - return Path.Combine(this.Folder, "TLO.local.Settings.xml"); - } - } - - public string Folder - { - get - { - return Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); - } - } - - public void Save() - { - lock (this) - { - try - { - if (!Directory.Exists(Path.GetDirectoryName(this.FileSettings))) - Directory.CreateDirectory(Path.GetDirectoryName(this.FileSettings)); - using (Stream stream = (Stream) File.Open(this.FileSettings, FileMode.Create, FileAccess.ReadWrite)) - { - this.LogLevel = new int?(this.LogLevel.HasValue ? this.LogLevel.Value : 0); - new XmlSerializer(typeof (Settings)).Serialize(stream, (object) this); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - Console.WriteLine(ex.StackTrace); - } - this._LastWriteTime = File.GetLastWriteTime(this.FileSettings); - } - } - - public void Read() - { - try - { - lock (this) - { - using (Stream stream = (Stream) File.Open(this.FileSettings, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - Settings settings = (Settings) new XmlSerializer(typeof (Settings)).Deserialize(stream); - this.IsUpdateStatistics = settings.IsUpdateStatistics; - this.CountDaysKeepHistory = settings.CountDaysKeepHistory; - this.PeriodRunAndStopTorrents = settings.PeriodRunAndStopTorrents; - this.CountSeedersReport = settings.CountSeedersReport; - this.IsAvgCountSeeders = settings.IsAvgCountSeeders; - this.KeeperName = settings.KeeperName; - this.KeeperPass = settings.KeeperPass; - this.IsSelectLessOrEqual = settings.IsSelectLessOrEqual; - this.IsNotSaveStatistics = settings.IsNotSaveStatistics; - this.LastUpdateTopics = settings.LastUpdateTopics; - this.ReportTop1 = settings.ReportTop1.Replace("\n", "\r\n").Replace("\r\r", "\r"); - this.ReportTop2 = settings.ReportTop2.Replace("\n", "\r\n").Replace("\r\r", "\r"); - this.ReportLine = settings.ReportLine.Replace("\n", "\r\n").Replace("\r\r", "\r"); - this.ReportBottom = settings.ReportBottom; - this.HostRuTrackerOrg = settings.HostRuTrackerOrg; - this.SetLogger(settings.LogLevel.HasValue ? settings.LogLevel.Value : 0); - this._LastWriteTime = File.GetLastWriteTime(this.FileSettings); - this.LoadDBInMemory = settings.LoadDBInMemory; - } - } - } - catch - { - this.Save(); - } - } - - public void Checking() - { - if (!(File.GetLastWriteTime(this.FileSettings) != this._LastWriteTime)) - return; - this.Read(); - } - - public static Settings Current - { - get - { - if (Settings._data == null) - Settings._data = new Settings(); - Settings._data.Checking(); - return Settings._data; - } - } - - public Settings() - { - this.KeeperName = string.Empty; - this.KeeperPass = string.Empty; - this.CountDaysKeepHistory = 7; - this.PeriodRunAndStopTorrents = 60; - this.CountSeedersReport = 10; - this.IsSelectLessOrEqual = true; - this.IsNotSaveStatistics = true; - this.ReportLine = "[*] %%Status%% [url=viewtopic.php?t=%%ID%%]%%Name%%[/url] %%Size%%"; - this.ReportTop1 = "[b]Актуально на:[/b] %%CreateDate%%\r\n\r\nОбщее количество хранимых раздач подраздела: %%CountTopics%% шт. (%%SizeTopics%%)"; - this.ReportTop2 = "%%Top1%%[spoiler=\"Раздачи, взятые на хранение, №№ %%NumberTopicsFirst%% - %%NumberTopicsLast%%\"]\r\n[list=1]\r\n%%ReportLines%%\r\n[/list]\r\n[/spoiler]"; - this.ReportBottom = ""; - this.HostRuTrackerOrg = "rutracker.org"; - } - - [XmlElement] - public int? LogLevel { get; set; } - - private void SetLogger(int logLevel) - { - if (this.LogLevel.HasValue && this.LogLevel.Value == logLevel) - return; - string str = "BI.Analytics.Expert.Other"; - if (Assembly.GetEntryAssembly() != (Assembly) null) - str = Assembly.GetEntryAssembly().ManifestModule.Name; - LoggingConfiguration loggingConfiguration = new LoggingConfiguration(); - FileTarget fileTarget = new FileTarget(); - fileTarget.Layout = (Layout) "${date:format=yyyy-MM-dd HH\\:mm\\:ss}\t${level}\t${message}"; - loggingConfiguration.AddTarget("logfile", (Target) fileTarget); - fileTarget.FileName = (Layout) Path.Combine(this.Folder, str + ".log"); - fileTarget.Encoding = Encoding.UTF8; - fileTarget.ArchiveAboveSize = 20971520L; - if (Environment.UserInteractive) - { - ColoredConsoleTarget coloredConsoleTarget = new ColoredConsoleTarget(); - loggingConfiguration.AddTarget("console", (Target) coloredConsoleTarget); - coloredConsoleTarget.Layout = (Layout) "${date:format=yyyy-MM-dd HH\\:mm\\:ss}\t${level}\t${message}\t${file}:${line}"; - LoggingRule loggingRule = new LoggingRule("*", NLog.LogLevel.Debug, (Target) coloredConsoleTarget); - loggingConfiguration.LoggingRules.Add(loggingRule); - } - LoggingRule loggingRule1 = logLevel > 0 ? (logLevel != 1 ? (logLevel != 2 ? new LoggingRule("*", NLog.LogLevel.Trace, (Target) fileTarget) : new LoggingRule("*", NLog.LogLevel.Debug, (Target) fileTarget)) : new LoggingRule("*", NLog.LogLevel.Info, (Target) fileTarget)) : new LoggingRule("*", NLog.LogLevel.Warn, (Target) fileTarget); - loggingConfiguration.LoggingRules.Add(loggingRule1); - LogManager.Configuration = loggingConfiguration; - Settings._logger.Info(string.Format("OS: {0} (Is64BitOperatingSystem: {1}, Version {2})", (object) Environment.OSVersion.VersionString, (object) Environment.Is64BitOperatingSystem, (object) Environment.OSVersion.Version.ToString())); - this.LogLevel = new int?(logLevel); - } - - [XmlAttribute] - public string KeeperName { get; set; } - - [XmlAttribute] - public string KeeperPass { get; set; } - - [XmlAttribute] - public bool IsUpdateStatistics { get; set; } - - [XmlAttribute] - public int CountDaysKeepHistory { get; set; } - - [XmlAttribute] - public int PeriodRunAndStopTorrents { get; set; } - - [XmlAttribute] - public int CountSeedersReport { get; set; } - - [XmlAttribute] - public bool IsAvgCountSeeders { get; set; } - - [XmlAttribute] - public bool IsSelectLessOrEqual { get; set; } - - [XmlAttribute] - public bool IsNotSaveStatistics { get; set; } - - [XmlAttribute] - public DateTime LastUpdateTopics { get; set; } - - [XmlElement] - public string ReportTop1 { get; set; } - - [XmlElement] - public string ReportTop2 { get; set; } - - [XmlElement] - public string ReportLine { get; set; } - - [XmlElement] - public string ReportBottom { get; set; } - - [XmlElement] - public string HostRuTrackerOrg { get; set; } - - public bool? LoadDBInMemory { get; set; } - } -} diff --git a/TLO.local.csproj b/TLO.local.csproj deleted file mode 100644 index 39f3add..0000000 --- a/TLO.local.csproj +++ /dev/null @@ -1,215 +0,0 @@ - - - - - Debug - AnyCPU - {CA8B075B-1558-4D79-B98E-79F05B0EBA06} - WinExe - TLO.local - v4.0 - - 512 - TLO.local - - - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - false - false - 3 - 2.7.0.%2a - false - true - false - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - hdd.ico - - - - - - 5C89A36D3F3A2B86A9F79572C94B997F53603550 - - - TLO.local_TemporaryKey.pfx - - - true - - - true - - - - - packages\NLog.4.6.3\lib\net40-client\NLog.dll - - - - - - - lib\Newtonsoft.Json.dll - - - packages\System.Data.SQLite.Core.1.0.110.0\lib\net40\System.Data.SQLite.dll - - - - - - - - - - - - - - True - True - ForumPages.resx - - - True - True - MainForm.resx - - - True - True - SelectCategory.resx - - - True - True - SettingsForm.resx - - - - - - - - - Component - - - - - Form - - - - - - - Form - - - Form - - - UserControl - - - - - - Form - - - Form - - - - - - ForumPages.cs - ResXFileCodeGenerator - ForumPages.Designer.cs - - - MainForm.cs - ResXFileCodeGenerator - MainForm.Designer.cs - - - SelectCategory.cs - ResXFileCodeGenerator - SelectCategory.Designer.cs - - - SettingsForm.cs - ResXFileCodeGenerator - SettingsForm.Designer.cs - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 - false - - - - - False - - - - - Exclude - False - File - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - \ No newline at end of file diff --git a/TLO.local.sln b/TLO.local.sln deleted file mode 100644 index 3306b25..0000000 --- a/TLO.local.sln +++ /dev/null @@ -1,24 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28803.352 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLO.local", "TLO.local.csproj", "{CA8B075B-1558-4D79-B98E-79F05B0EBA06}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CA8B075B-1558-4D79-B98E-79F05B0EBA06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CA8B075B-1558-4D79-B98E-79F05B0EBA06}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA8B075B-1558-4D79-B98E-79F05B0EBA06}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CA8B075B-1558-4D79-B98E-79F05B0EBA06}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DB7410F5-AFC2-420F-B46B-B0449F9EC308} - EndGlobalSection -EndGlobal diff --git a/TLO.sln b/TLO.sln new file mode 100644 index 0000000..3eb57e7 --- /dev/null +++ b/TLO.sln @@ -0,0 +1,15 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLO", "TLO\TLO.csproj", "{636EBECD-92E1-45FD-87A1-129E110C72AA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {636EBECD-92E1-45FD-87A1-129E110C72AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {636EBECD-92E1-45FD-87A1-129E110C72AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {636EBECD-92E1-45FD-87A1-129E110C72AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {636EBECD-92E1-45FD-87A1-129E110C72AA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/TLO.sln.DotSettings.user b/TLO.sln.DotSettings.user new file mode 100644 index 0000000..50a802b --- /dev/null +++ b/TLO.sln.DotSettings.user @@ -0,0 +1,7 @@ + + <AssemblyExplorer> + <Assembly Path="C:\Users\maestroprog\RiderProjects\TLO\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll" /> + <Assembly Path="/home/maestroprog/RiderProjects/TLO/packages/NLog.4.6.8/lib/net45/NLog.dll" /> + <Assembly Path="/home/maestroprog/RiderProjects/TLO/packages/AngleSharp.1.0.0-alpha-819/lib/net472/AngleSharp.dll" /> +</AssemblyExplorer> + True \ No newline at end of file diff --git a/TLO/App.config b/TLO/App.config new file mode 100644 index 0000000..fcd1068 --- /dev/null +++ b/TLO/App.config @@ -0,0 +1,20 @@ + + + + +
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TLO/Clients/ClientLocalDb.cs b/TLO/Clients/ClientLocalDb.cs new file mode 100644 index 0000000..daa9055 --- /dev/null +++ b/TLO/Clients/ClientLocalDb.cs @@ -0,0 +1,1145 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SQLite; +using System.IO; +using System.Linq; +using System.Reflection; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class ClientLocalDb + { + private static ClientLocalDb? _current; + private static Logger? _logger; + private readonly SQLiteConnection _conn; + + public static ClientLocalDb Current => _current ??= new ClientLocalDb(); + + public static string FileDatabase => + Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Database.db"); + + private ClientLocalDb() + { + if (_logger == null) _logger = LogManager.GetLogger("SQLiteDb"); + + if (!File.Exists(FileDatabase)) + { + _conn = DbConnectionCreator.Instance.Connection; + CreateDatabase(); + DbConnectionCreator.Instance.Persist(); + } + + _conn = DbConnectionCreator.Instance.Connection; + UpdateDataBase(); + } + + public void Reconnect() + { + if (DbConnectionCreator.Instance.Reconnect()) + { + _current = null; + } + } + + public SQLiteCommand CreateCommand() + { + return _conn.CreateCommand(); + } + + public void SaveToDatabase() + { + DbConnectionCreator.Instance.Persist(); + } + + private void CreateDatabase() + { + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @" +CREATE TABLE Category(CategoryID INTEGER PRIMARY KEY ASC, ParentID INTEGER, OrderID INT, Name TEXT NOT NULL, FullName TEXT NOT NULL, IsEnable BIT, CountSeeders int, + TorrentClientUID TEXT, Folder TEXT, AutoDownloads INT, LastUpdateTopics DATETIME, LastUpdateStatus DATETIME, Label TEXT, ReportTopicID INT); +CREATE TABLE Topic (TopicID INT PRIMARY KEY ASC, CategoryID INT, Name TEXT, Hash TEXT, Size INTEGER, Seeders INT, AvgSeeders DECIMAL(18,4), Status INT, IsActive BIT, IsDeleted BIT, IsKeep BIT, IsKeepers BIT, IsBlackList BIT, IsDownload BIT, RegTime DATETIME, PosterID INT); +CREATE INDEX IX_Topic__Hash ON Topic (Hash); +CREATE TABLE TopicStatusHystory (TopicID INT NOT NULL, Date DateTime NOT NULL, Seeders INT, PRIMARY KEY(TopicID ASC, Date ASC)); +CREATE TABLE TorrentClient(UID NVARCHAR(50) PRIMARY KEY ASC NOT NULL, Name NVARCHAR(100) NOT NULL, Type VARCHAR(50) NOT NULL, ServerName NVARCHAR(50) NOT NULL, ServerPort INT NOT NULL, UserName NVARCHAR(50), UserPassword NVARCHAR(50), LastReadHash DATETIME); +CREATE TABLE Report(CategoryID INT NOT NULL, ReportNo INT NOT NULL, URL TEXT, Report TEXT, PRIMARY KEY(CategoryID ASC, ReportNo ASC)); +CREATE TABLE Keeper (KeeperName nvarchar(100) not null, CategoryID int not null, Count INT NOT NULL, Size DECIMAL(18,4) NOT NULL, PRIMARY KEY(KeeperName ASC, CategoryID ASC)); +CREATE TABLE KeeperToTopic(KeeperName NVARCHAR(50) NOT NULL, CategoryID INT NULL, TopicID INT NOT NULL, PRIMARY KEY(KeeperName ASC, TopicID ASC)); +CREATE TABLE User (UserID INT PRIMARY KEY ASC NOT NULL, Name NVARCHAR(100) NOT NULL); +"; + command.ExecuteNonQuery(); + } + } + + public void ClearDatabase() + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + var intSet = new HashSet(); + command.Transaction = sqLiteTransaction; + command.CommandText = "DELETE FROM Topic"; + command.ExecuteNonQuery(); + command.CommandText = "DELETE FROM TopicStatusHystory"; + command.ExecuteNonQuery(); + command.CommandText = "UPDATE Report SET Report = ''"; + command.ExecuteNonQuery(); + } + + sqLiteTransaction.Commit(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = "vacuum;"; + command.ExecuteNonQuery(); + } + } + } + + public void UpdateDataBase() + { + using (var command = _conn.CreateCommand()) + { + command.CommandText = "PRAGMA user_version"; + var result = (long) command.ExecuteScalar(); + for (var i = 0; i <= 1; i++, result++) + switch (result) + { + case 0: + command.CommandText = + @"CREATE INDEX keepername_topicid_idx ON KeeperToTopic (TopicID, KeeperName)"; + command.ExecuteNonQuery(); + continue; + default: + command.CommandText = $"PRAGMA user_version={i}"; + command.ExecuteNonQuery(); + break; + } + } + } + + public IEnumerable GetUsers() + { + var userInfoList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = "SELECT * FROM User"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + userInfoList.Add(new UserInfo + { + UserID = sqLiteDataReader.GetInt32(0), + Name = sqLiteDataReader.GetString(1) + }); + } + } + + return userInfoList; + } + + public void SaveUsers(IEnumerable data) + { + if (data == null || data.Count() == 0) + return; + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = "INSERT OR REPLACE INTO User(UserID, Name) VALUES(@UserID, @Name);"; + command.Parameters.Add("@UserID", DbType.Int32); + command.Parameters.Add("@Name", DbType.String); + command.Prepare(); + foreach (var userInfo in data) + { + command.Parameters[0].Value = userInfo.UserID; + command.Parameters[1].Value = userInfo.Name ?? "<Удален>"; + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public int[] GetNoUsers() + { + var intList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @" +SELECT DISTINCT t.PosterID +FROM + Topic AS t + LEFT JOIN User AS u ON (t.PosterID = u.UserID) +WHERE + t.PosterID IS NOT NULL AND u.Name IS NULL"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + { + var posterId = sqLiteDataReader.GetInt32(0); + if (posterId > 0) intList.Add(posterId); + } + } + } + + return intList.ToArray(); + } + + public void CategoriesSave(IEnumerable data, bool isLoad = false) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + var hash = new HashSet(); + command.Transaction = sqLiteTransaction; + command.CommandText = string.Format("select CategoryID FROM Category WHERE CategoryID IN ({0})", + string.Join(",", data.Select(x => x.CategoryID))); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + hash.Add(sqLiteDataReader.GetInt32(0)); + } + + if (isLoad) + { + command.CommandText = + "UPDATE Category SET ParentID = @ParentID, OrderID = @OrderID, Name = @Name, FullName = @FullName WHERE CategoryID = @ID"; + var source = data; + foreach (var category in source.Where(x => hash.Contains(x.CategoryID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@ID", category.CategoryID); + command.Parameters.AddWithValue("@ParentID", category.ParentID); + command.Parameters.AddWithValue("@OrderID", category.OrderID); + command.Parameters.AddWithValue("@Name", category.Name); + command.Parameters.AddWithValue("@FullName", + string.IsNullOrWhiteSpace(category.FullName) ? category.Name : category.FullName); + command.ExecuteNonQuery(); + } + } + else + { + command.CommandText = "UPDATE Category SET IsEnable = 0 WHERE IsEnable = 1"; + command.ExecuteNonQuery(); + command.CommandText = + "UPDATE Category SET IsEnable = @IsEnable, Folder = @Folder, LastUpdateTopics = @LastUpdateTopics, LastUpdateStatus = @LastUpdateStatus, CountSeeders = @CountSeeders, TorrentClientUID = @TorrentClientUID, Label = @Label WHERE CategoryID = @ID"; + var source = data; + foreach (var category in source.Where(x => hash.Contains(x.CategoryID))) + { + var str = string.Format("{0}|{1}|{2}|{3}", (object) category.Folder, + (object) category.CreateSubFolder, + category.IsSaveTorrentFiles ? (object) "1" : (object) "0", + category.IsSaveWebPage ? (object) "1" : (object) "0"); + command.Parameters.Clear(); + command.Parameters.AddWithValue("@ID", category.CategoryID); + command.Parameters.AddWithValue("@IsEnable", category.IsEnable); + command.Parameters.AddWithValue("@CountSeeders", category.CountSeeders); + command.Parameters.AddWithValue("@TorrentClientUID", category.TorrentClientUID.ToString()); + command.Parameters.AddWithValue("@Folder", str); + command.Parameters.AddWithValue("@LastUpdateTopics", category.LastUpdateTopics); + command.Parameters.AddWithValue("@LastUpdateStatus", category.LastUpdateStatus); + command.Parameters.AddWithValue("@Label", category.Label); + command.ExecuteNonQuery(); + } + } + + command.CommandText = + @"INSERT OR REPLACE INTO Category (CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, Label) +VALUES(@ID, @ParentID, @OrderID, @Name, @FullName, @IsEnable, @Folder, @LastUpdateTopics, @LastUpdateStatus, @Label)"; + var source1 = data; + foreach (var category in source1.Where(x => !hash.Contains(x.CategoryID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@ID", category.CategoryID); + command.Parameters.AddWithValue("@ParentID", category.ParentID); + command.Parameters.AddWithValue("@OrderID", category.OrderID); + command.Parameters.AddWithValue("@Name", category.Name); + command.Parameters.AddWithValue("@FullName", + string.IsNullOrWhiteSpace(category.FullName) ? category.Name : category.FullName); + command.Parameters.AddWithValue("@IsEnable", category.IsEnable); + command.Parameters.AddWithValue("@CountSeeders", category.CountSeeders); + command.Parameters.AddWithValue("@Folder", category.Folder); + command.Parameters.AddWithValue("@LastUpdateTopics", category.LastUpdateTopics); + command.Parameters.AddWithValue("@LastUpdateStatus", category.LastUpdateStatus); + command.Parameters.AddWithValue("@Label", category.Label); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public List GetCategories() + { + var categoryList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @" +SELECT CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, CountSeeders, TorrentClientUID, ReportTopicID, Label FROM Category"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + { + var category = new Category + { + CategoryID = sqLiteDataReader.GetInt32(0), + ParentID = sqLiteDataReader.GetInt32(1), + OrderID = sqLiteDataReader.GetInt32(2), + Name = sqLiteDataReader.GetString(3), + FullName = sqLiteDataReader.GetString(4), + IsEnable = sqLiteDataReader.GetBoolean(5), + CountSeeders = sqLiteDataReader.IsDBNull(9) ? 2 : sqLiteDataReader.GetInt32(9), + TorrentClientUID = sqLiteDataReader.IsDBNull(10) + ? Guid.Empty + : Guid.Parse(sqLiteDataReader.GetString(10)), + LastUpdateTopics = sqLiteDataReader.GetDateTime(7), + LastUpdateStatus = sqLiteDataReader.GetDateTime(8), + ReportList = sqLiteDataReader.IsDBNull(11) ? string.Empty : sqLiteDataReader.GetString(11), + Label = sqLiteDataReader.IsDBNull(12) ? string.Empty : sqLiteDataReader.GetString(12) + }; + var str = sqLiteDataReader.IsDBNull(6) ? "" : sqLiteDataReader.GetString(6); + if (!string.IsNullOrWhiteSpace(str)) + { + var strArray = str.Split('|'); + if (strArray.Length >= 1) + category.Folder = strArray[0]; + if (strArray.Length >= 2) + category.CreateSubFolder = int.Parse(strArray[1]); + if (strArray.Length >= 3) + { + category.IsSaveTorrentFiles = strArray[2] == "1"; + category.FolderTorrentFile = Path.Combine(category.Folder, "!!!Torrent-files!!!"); + } + + if (strArray.Length >= 4) + { + category.IsSaveWebPage = strArray[3] == "1"; + category.FolderSavePageForum = Path.Combine(category.Folder, "!!!Web-pages!!!"); + } + } + + categoryList.Add(category); + } + } + } + + return categoryList; + } + + public List GetCategoriesEnable(bool withUnknown = false) + { + var categoryList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @" +SELECT CategoryID, ParentID, OrderID, Name, FullName, IsEnable, Folder, LastUpdateTopics, LastUpdateStatus, CountSeeders, TorrentClientUID, Label FROM Category WHERE IsEnable = 1 ORDER BY FullName"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + { + var category = new Category + { + CategoryID = sqLiteDataReader.GetInt32(0), + ParentID = sqLiteDataReader.GetInt32(1), + OrderID = sqLiteDataReader.GetInt32(2), + Name = sqLiteDataReader.GetString(3), + FullName = sqLiteDataReader.GetString(4), + IsEnable = sqLiteDataReader.GetBoolean(5), + CountSeeders = sqLiteDataReader.IsDBNull(9) ? 2 : sqLiteDataReader.GetInt32(9), + TorrentClientUID = sqLiteDataReader.IsDBNull(10) + ? Guid.Empty + : Guid.Parse(sqLiteDataReader.GetString(10)), + LastUpdateTopics = sqLiteDataReader.GetDateTime(7), + LastUpdateStatus = sqLiteDataReader.GetDateTime(8), + Label = sqLiteDataReader.IsDBNull(11) ? string.Empty : sqLiteDataReader.GetString(11) + }; + var str = sqLiteDataReader.IsDBNull(6) ? "" : sqLiteDataReader.GetString(6); + if (!string.IsNullOrWhiteSpace(str)) + { + var strArray = str.Split('|'); + if (strArray.Length >= 1) + category.Folder = strArray[0]; + if (strArray.Length >= 2) + category.CreateSubFolder = int.Parse(strArray[1]); + if (strArray.Length >= 3) + { + category.IsSaveTorrentFiles = strArray[2] == "1"; + category.FolderTorrentFile = Path.Combine(category.Folder, "!!!Torrent-files!!!"); + } + + if (strArray.Length >= 4) + { + category.IsSaveWebPage = strArray[3] == "1"; + category.FolderSavePageForum = Path.Combine(category.Folder, "!!!Web-pages!!!"); + } + } + + categoryList.Add(category); + } + } + } + + if (withUnknown) + { + var unknown = new Category + { + FullName = "Неизвестные", + CategoryID = -1 + }; + categoryList.Add(unknown); + } + + return categoryList; + } + + public void ResetFlagsTopicDownloads() + { + using (var command = _conn.CreateCommand()) + { + command.CommandText = "UPDATE Topic SET IsKeep = 0, IsDownload = 0"; + command.ExecuteNonQuery(); + } + } + + public void SaveTopicInfo(List data, bool isUpdateTopic = false) + { + var dateTime = new DateTime(2000, 1, 1); + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + if (isUpdateTopic) + { + command.CommandText = + "UPDATE Category SET LastUpdateTopics = @LastUpdateTopics WHERE CategoryID = @CategoryID"; + foreach (var num in data.Select(x => x.CategoryID).Distinct()) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@CategoryID", num); + command.Parameters.AddWithValue("@LastUpdateTopics", DateTime.Now); + command.ExecuteNonQuery(); + } + } + + command.CommandText = string.Format("SELECT TopicID FROM Topic WHERE TopicID IN ({0})", + string.Join(",", data.Select(x => x.TopicID))); + var list = new List(); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + list.Add(sqLiteDataReader.GetInt32(0)); + } + + if (isUpdateTopic) + { + command.CommandText = + "UPDATE Topic SET CategoryID = @CategoryID, Name = @Name, Hash = @Hash, Size = @Size, Seeders = @Seeders, Status = @Status, IsDeleted = @IsDeleted, RegTime = @RegTime, PosterID = @PosterID WHERE TopicID = @TopicID;"; + var source = data; + foreach (var topicInfo in source.Where(x => list.Contains(x.TopicID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@TopicID", topicInfo.TopicID); + command.Parameters.AddWithValue("@CategoryID", topicInfo.CategoryID); + command.Parameters.AddWithValue("@Name", topicInfo.Name2); + command.Parameters.AddWithValue("@Hash", topicInfo.Hash); + command.Parameters.AddWithValue("@Size", topicInfo.Size); + command.Parameters.AddWithValue("@Seeders", topicInfo.Seeders); + command.Parameters.AddWithValue("@Status", topicInfo.Status); + command.Parameters.AddWithValue("@IsDeleted", 0); + command.Parameters.AddWithValue("@RegTime", + topicInfo.RegTime < dateTime ? dateTime : topicInfo.RegTime); + command.Parameters.AddWithValue("@PosterID", topicInfo.PosterID); + command.ExecuteNonQuery(); + } + } + else + { + command.CommandText = + "UPDATE Topic SET CategoryID = @CategoryID, Name = @Name, Hash = @Hash, Size = @Size, Seeders = @Seeders, Status = @Status, IsDeleted = @IsDeleted, IsKeep = @IsKeep, IsKeepers = @IsKeepers, IsBlackList = @IsBlackList, IsDownload = @IsDownload WHERE TopicID = @TopicID;"; + var source = data; + foreach (var topicInfo in source.Where(x => list.Contains(x.TopicID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@TopicID", topicInfo.TopicID); + command.Parameters.AddWithValue("@CategoryID", topicInfo.CategoryID); + command.Parameters.AddWithValue("@Name", topicInfo.Name2); + command.Parameters.AddWithValue("@Hash", topicInfo.Hash); + command.Parameters.AddWithValue("@Size", topicInfo.Size); + command.Parameters.AddWithValue("@Seeders", topicInfo.Seeders); + command.Parameters.AddWithValue("@Status", topicInfo.Status); + command.Parameters.AddWithValue("@IsDeleted", 0); + command.Parameters.AddWithValue("@IsKeep", topicInfo.IsKeep); + command.Parameters.AddWithValue("@IsKeepers", topicInfo.IsKeeper); + command.Parameters.AddWithValue("@IsBlackList", topicInfo.IsBlackList); + command.Parameters.AddWithValue("@IsDownload", topicInfo.IsDownload); + command.ExecuteNonQuery(); + } + } + + command.CommandText = + @" +INSERT OR REPLACE INTO Topic (TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, RegTime, PosterID) +VALUES(@TopicID, @CategoryID, @Name, @Hash, @Size, @Seeders, @Status, @IsActive, @IsDeleted, @IsKeep, @IsKeepers, @IsBlackList, @IsDownload, @RegTime, @PosterID);"; + var source1 = data; + foreach (var topicInfo in source1.Where(x => !list.Contains(x.TopicID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@TopicID", topicInfo.TopicID); + command.Parameters.AddWithValue("@CategoryID", topicInfo.CategoryID); + command.Parameters.AddWithValue("@Name", topicInfo.Name2); + command.Parameters.AddWithValue("@Hash", topicInfo.Hash); + command.Parameters.AddWithValue("@Size", topicInfo.Size); + command.Parameters.AddWithValue("@Seeders", topicInfo.Seeders); + command.Parameters.AddWithValue("@Status", topicInfo.Status); + command.Parameters.AddWithValue("@IsActive", 1); + command.Parameters.AddWithValue("@IsDeleted", 0); + command.Parameters.AddWithValue("@IsKeep", topicInfo.IsKeep); + command.Parameters.AddWithValue("@IsKeepers", topicInfo.IsKeeper); + command.Parameters.AddWithValue("@IsBlackList", topicInfo.IsBlackList); + command.Parameters.AddWithValue("@IsDownload", topicInfo.IsDownload); + command.Parameters.AddWithValue("@RegTime", + topicInfo.RegTime < dateTime ? dateTime : topicInfo.RegTime); + command.Parameters.AddWithValue("@PosterID", topicInfo.PosterID); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + + SaveStatus(data.Select(x => new int[2] + { + x.TopicID, + x.Seeders + }).ToArray(), true); + } + + internal void DeleteTopicsByCategoryId(int categoryId) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.Parameters.AddWithValue("@categoryID", categoryId); + command.CommandText = "UPDATE Topic SET IsDeleted = 1 WHERE CategoryID = @categoryID;"; + command.ExecuteNonQuery(); + } + + sqLiteTransaction.Commit(); + } + } + + public void ClearHistoryStatus() + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.Parameters.Add("@Date", DbType.DateTime); + command.Parameters[0].Value = DateTime.Now.Date.AddDays(-Settings.Current.CountDaysKeepHistory); + command.CommandText = "DELETE FROM TopicStatusHystory WHERE Date <= @Date;"; + command.ExecuteNonQuery(); + } + + sqLiteTransaction.Commit(); + } + } + + public void SaveStatus(int[][] data, bool isUpdateStatus = false) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = + @" +UPDATE Topic SET Seeders = @Seeders WHERE TopicID = @TopicID; +INSERT OR REPLACE INTO TopicStatusHystory VALUES(@TopicID, @Date, @Seeders); +"; + if (Settings.Current.IsNotSaveStatistics) + command.CommandText = "UPDATE Topic SET Seeders = @Seeders WHERE TopicID = @TopicID;"; + command.Parameters.Clear(); + command.Parameters.Add("@Date", DbType.DateTime); + command.Parameters.Add("@TopicID", DbType.Int32); + command.Parameters.Add("@Seeders", DbType.Int32); + command.Parameters[0].Value = DateTime.Now; + foreach (var numArray in data) + { + command.Parameters[1].Value = numArray[0]; + command.Parameters[2].Value = numArray[1]; + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public List GetTopicsByCategory(int categoyid) + { + var dateTime = new DateTime(2000, 1, 1); + var topicInfoList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @"SELECT TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, PosterID +FROM Topic WHERE (CategoryID = @CategoryID OR @CategoryID = -1) AND IsDeleted = 0 AND Status NOT IN (7,4,11,5) and Hash IS NOT NULL"; + command.Parameters.AddWithValue("@CategoryID", categoyid); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + topicInfoList.Add(new TopicInfo + { + TopicID = sqLiteDataReader.GetInt32(0), + CategoryID = sqLiteDataReader.GetInt32(1), + Name2 = sqLiteDataReader.GetString(2), + Hash = sqLiteDataReader.GetString(3), + Size = sqLiteDataReader.GetInt64(4), + Seeders = sqLiteDataReader.GetInt32(5), + Status = sqLiteDataReader.GetInt32(6), + IsKeep = sqLiteDataReader.GetBoolean(9), + IsKeeper = sqLiteDataReader.GetBoolean(10), + IsBlackList = sqLiteDataReader.GetBoolean(11), + IsDownload = sqLiteDataReader.GetBoolean(12), + AvgSeeders = sqLiteDataReader.IsDBNull(13) + ? new decimal?() + : sqLiteDataReader.GetDecimal(13), + RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), + PosterID = sqLiteDataReader.IsDBNull(15) ? 0 : sqLiteDataReader.GetInt32(15) + }); + } + } + + return topicInfoList; + } + + public List GetTopicsAllByCategory(int categoyid) + { + var dateTime = new DateTime(2000, 1, 1); + var topicInfoList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @"SELECT TopicID, CategoryID, Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, PosterID +FROM Topic WHERE (CategoryID = @CategoryID OR @CategoryID = -1) and Hash is null"; + command.Parameters.AddWithValue("@CategoryID", categoyid); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + topicInfoList.Add(new TopicInfo + { + TopicID = sqLiteDataReader.GetInt32(0), + CategoryID = sqLiteDataReader.GetInt32(1), + Name2 = sqLiteDataReader.GetString(2), + Hash = sqLiteDataReader.GetString(3), + Size = sqLiteDataReader.GetInt64(4), + Seeders = sqLiteDataReader.GetInt32(5), + Status = sqLiteDataReader.GetInt32(6), + IsKeep = sqLiteDataReader.GetBoolean(9), + IsKeeper = sqLiteDataReader.GetBoolean(10), + IsBlackList = sqLiteDataReader.GetBoolean(11), + IsDownload = sqLiteDataReader.GetBoolean(12), + AvgSeeders = sqLiteDataReader.IsDBNull(13) + ? new decimal?() + : sqLiteDataReader.GetDecimal(13), + RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), + PosterID = sqLiteDataReader.IsDBNull(15) ? 0 : sqLiteDataReader.GetInt32(15) + }); + } + } + + return topicInfoList; + } + + public List GetTopics(DateTime regTime, int categoyid, int? countSeeders, int? avgCountSeeders, + bool? isKeep, bool? isKeepers, bool? isDownload, bool? isBlack, bool? isPoster) + { + var dateTime = new DateTime(2000, 1, 1); + var topicInfoList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = @" +SELECT t.TopicID, t.CategoryID, t.Name, Hash, Size, Seeders, Status, IsActive, IsDeleted, IsKeep, IsKeepers, IsBlackList, IsDownload, AvgSeeders, RegTime, CAST(CASE WHEN @UserName = u.Name THEN 1 ELSE 0 END AS BIT), +COUNT(kt.TopicID) + CASE WHEN IsKeep THEN 1 ELSE 0 END AS KeepersCount +FROM Topic AS t +LEFT JOIN User AS u ON (t.PosterID = u.UserID) +LEFT JOIN KeeperToTopic AS kt ON (kt.TopicID = t.TopicID AND kt.KeeperName <> @UserName) +WHERE + t.CategoryID = @CategoryID + AND t.RegTime < @RegTime + AND Status NOT IN (7,4,11,5) +" + ( + countSeeders.HasValue + ? string.Format(" AND Seeders {1} {0}", countSeeders.Value, + Settings.Current.IsSelectLessOrEqual ? " <= " : " = ") + : "" + ) + + (avgCountSeeders.HasValue + ? string.Format(" AND AvgSeeders {1} {0}", avgCountSeeders.Value, + Settings.Current.IsSelectLessOrEqual ? " <= " : " = ") + : "") + + (isKeep.HasValue ? string.Format(" AND IsKeep = {0}", isKeep.Value ? 1 : 0) : "") + + (isKeepers.HasValue + ? string.Format(" AND CAST(CASE WHEN kt.TopicID IS NOT NULL THEN 1 ELSE 0 END " + (!isKeep.HasValue ? "OR CAST(IsKeep AS INT)" : "") + " AS BIT) = {0}", + isKeepers.Value ? 1 : 0) + : "") + + (isDownload.HasValue ? string.Format(" AND IsDownload = {0}", isDownload.Value ? 1 : 0) : "") + + (isPoster.HasValue ? string.Format(" AND @UserName = u.Name", isPoster.Value ? 1 : 0) : "") + + string.Format(" AND IsBlackList = {0}", !isBlack.HasValue || !isBlack.Value ? 0 : 1) + + " AND IsDeleted = 0 GROUP BY t.TopicID HAVING t.TopicID IS NOT NULL ORDER BY t.Seeders, t.Name"; + command.Parameters.AddWithValue("@CategoryID", categoyid); + command.Parameters.AddWithValue("@RegTime", regTime); + command.Parameters.AddWithValue("@UserName", + string.IsNullOrWhiteSpace(Settings.Current.KeeperName) ? "-" : Settings.Current.KeeperName); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + topicInfoList.Add(new TopicInfo + { + TopicID = sqLiteDataReader.GetInt32(0), + CategoryID = sqLiteDataReader.GetInt32(1), + Name2 = sqLiteDataReader.IsDBNull(2) ? string.Empty : sqLiteDataReader.GetString(2), + Hash = sqLiteDataReader.IsDBNull(3) ? string.Empty : sqLiteDataReader.GetString(3), + Size = sqLiteDataReader.GetInt64(4), + Seeders = sqLiteDataReader.GetInt32(5), + Status = sqLiteDataReader.GetInt32(6), + IsKeep = sqLiteDataReader.GetBoolean(9), + KeeperCount = sqLiteDataReader.GetInt32(16), + IsBlackList = sqLiteDataReader.GetBoolean(11), + IsDownload = sqLiteDataReader.GetBoolean(12), + AvgSeeders = sqLiteDataReader.IsDBNull(13) + ? new decimal?() + : Math.Round(sqLiteDataReader.GetDecimal(13), 3), + RegTime = sqLiteDataReader.IsDBNull(14) ? dateTime : sqLiteDataReader.GetDateTime(14), + IsPoster = sqLiteDataReader.GetBoolean(15) + }); + } + } + + return topicInfoList; + } + + public void SetTorrentClientHash(List data) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = + "UPDATE Topic SET IsDownload = @IsDownload, IsKeep = @IsKeep WHERE Hash = @Hash;"; + foreach (var topicInfo in data) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@Hash", topicInfo.Hash); + command.Parameters.AddWithValue("@IsDownload", topicInfo.IsDownload); + command.Parameters.AddWithValue("@IsKeep", topicInfo.IsKeep); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public void SaveTorrentClients(IEnumerable data, bool isUpdateList = false) + { + var tc = GetTorrentClients(); + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + if (isUpdateList) + { + command.CommandText = "DELETE FROM TorrentClient WHERE UID = @UID"; + var source = tc; + foreach (var torrentClientInfo in source.Where(x => + !data.Select(y => y.UID).Contains(x.UID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@UID", torrentClientInfo.UID.ToString()); + command.ExecuteNonQuery(); + } + } + + command.CommandText = + "UPDATE TorrentClient SET Name = @Name, Type = @Type, ServerName = @ServerName, ServerPort = @ServerPort, UserName = @UserName, UserPassword = @UserPassword, LastReadHash = @LastReadHash WHERE UID = @UID"; + var source1 = data; + foreach (var torrentClientInfo in source1.Where(x => + tc.Select(y => y.UID).Contains(x.UID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@UID", torrentClientInfo.UID.ToString()); + command.Parameters.AddWithValue("@Name", torrentClientInfo.Name); + command.Parameters.AddWithValue("@Type", torrentClientInfo.Type); + command.Parameters.AddWithValue("@ServerName", torrentClientInfo.ServerName); + command.Parameters.AddWithValue("@ServerPort", torrentClientInfo.ServerPort); + command.Parameters.AddWithValue("@UserName", torrentClientInfo.UserName); + command.Parameters.AddWithValue("@UserPassword", torrentClientInfo.UserPassword); + command.Parameters.AddWithValue("@LastReadHash", torrentClientInfo.LastReadHash); + command.ExecuteNonQuery(); + } + + command.CommandText = + "INSERT INTO TorrentClient (UID, Name, Type, ServerName, ServerPort, UserName, UserPassword, LastReadHash) VALUES(@UID, @Name, @Type, @ServerName, @ServerPort, @UserName, @UserPassword, @LastReadHash)"; + var source2 = data; + foreach (var torrentClientInfo in source2.Where(x => + !tc.Select(y => y.UID).Contains(x.UID))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@UID", torrentClientInfo.UID.ToString()); + command.Parameters.AddWithValue("@Name", torrentClientInfo.Name); + command.Parameters.AddWithValue("@Type", torrentClientInfo.Type); + command.Parameters.AddWithValue("@ServerName", torrentClientInfo.ServerName); + command.Parameters.AddWithValue("@ServerPort", torrentClientInfo.ServerPort); + command.Parameters.AddWithValue("@UserName", torrentClientInfo.UserName); + command.Parameters.AddWithValue("@UserPassword", torrentClientInfo.UserPassword); + command.Parameters.AddWithValue("@LastReadHash", torrentClientInfo.LastReadHash); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public List GetTorrentClients() + { + var torrentClientInfoList = new List(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = "SELECT * FROM TorrentClient"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + torrentClientInfoList.Add(new TorrentClientInfo + { + UID = Guid.Parse(sqLiteDataReader.GetString(0)), + Name = sqLiteDataReader.GetString(1), + Type = sqLiteDataReader.GetString(2), + ServerName = sqLiteDataReader.GetString(3), + ServerPort = sqLiteDataReader.GetInt32(4), + UserName = sqLiteDataReader.GetString(5), + UserPassword = sqLiteDataReader.GetString(6), + LastReadHash = sqLiteDataReader.GetDateTime(7) + }); + } + } + + return torrentClientInfoList; + } + + public void SaveKeepOtherKeepers(Dictionary>> data) + { + if (data == null) + return; + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandTimeout = 60000; + foreach (var keyValuePair in data) + { + var dt = keyValuePair; + var array = dt.Value.Item2.Distinct().ToArray(); + var intListArray = + new List[array.Length % 500 == 0 ? array.Length / 500 : array.Length / 500 + 1]; + for (var index1 = 0; index1 < array.Length; ++index1) + { + var index2 = index1 / 500; + if (intListArray[index2] == null) + intListArray[index2] = new List(); + intListArray[index2].Add(array[index1]); + } + + foreach (var source in intListArray) + { + command.Parameters.Clear(); + command.CommandText = + "INSERT OR REPLACE INTO KeeperToTopic(KeeperName, CategoryID, TopicID)\r\n" + + string.Join("UNION ", + source.Select(x => + string.Format("SELECT @KeeperName, {2}, {1}\r\n", dt.Key, x, dt.Value.Item1))); + command.Parameters.AddWithValue("@KeeperName", dt.Key.Replace("", "").Trim()); + command.ExecuteNonQuery(); + } + } + } + + sqLiteTransaction.Commit(); + } + } + + private void SaveKeepStatus(string keepName, List> data) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = + "INSERT OR REPLACE INTO Keeper VALUES(@KeeperName, @CategoryID, @Count, @Size)"; + command.Parameters.Add("@KeeperName", DbType.String); + command.Parameters.Add("@CategoryID", DbType.Int32); + command.Parameters.Add("@Count", DbType.Int64); + command.Parameters.Add("@Size", DbType.Decimal); + if (string.IsNullOrWhiteSpace(keepName)) + keepName = Settings.Current.KeeperName; + if (string.IsNullOrWhiteSpace(keepName)) + return; + foreach (var tuple in data) + { + command.Parameters[0].Value = keepName.Replace("", "").Trim(); + command.Parameters[1].Value = tuple.Item1; + command.Parameters[2].Value = tuple.Item2; + command.Parameters[3].Value = Math.Round(tuple.Item3, 2); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public void ClearReports() + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = "UPDATE Report SET Report = @Report WHERE ReportNo <> 0"; + command.Parameters.AddWithValue("@Report", "Удалено"); + command.ExecuteNonQuery(); + } + + sqLiteTransaction.Commit(); + } + } + + public List> GetStatisticsByAllUsers() + { + var tupleList = new List>(); + var flag = GetTorrentClients().Any(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @"INSERT OR REPLACE INTO Keeper SELECT 'All', CategoryID, COUNT(*) Cnt, SUM(Size) / 1073741824.0 Size FROM Topic WHERE IsDeleted = 0 AND CategoryID <> 0 GROUP BY CategoryID; +INSERT OR REPLACE INTO Keeper SELECT kt.KeeperName, kt.CategoryID, COUNT(*), CAST(SUM(t.Size) / 1073741824.0 AS NUMERIC(18,4)) Size + FROM KeeperToTopic AS kt JOIN Topic AS t ON (kt.TopicID = t.TopicID AND kt.KeeperName <> @KeeperName) group by kt.KeeperName, kt.CategoryID; +INSERT OR REPLACE INTO Keeper SELECT @KeeperName, CategoryID, COUNT(*) Cnt, CAST(SUM(Size) / 1073741824.0 AS NUMERIC(18,4)) Size FROM Topic + WHERE IsDeleted = 0 AND IsKeep = 1 AND (Seeders <= @Seeders OR @Seeders = -1) AND Status NOT IN (7, 4,11,5) AND IsBlackList = 0 GROUP BY CategoryID; +"; + command.Parameters.AddWithValue("@KeeperName", flag ? Settings.Current.KeeperName : ""); + command.Parameters.AddWithValue("@Seeders", Settings.Current.CountSeedersReport); + command.ExecuteNonQuery(); + command.CommandText = "SELECT KeeperName, CategoryID, Count, Size FROM Keeper"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + tupleList.Add(new Tuple(sqLiteDataReader.GetInt32(1), + sqLiteDataReader.GetString(0), sqLiteDataReader.GetInt32(2), + Math.Round(sqLiteDataReader.GetDecimal(3), 3))); + } + } + + return tupleList; + } + + public void SaveReports(Dictionary> reports) + { + foreach (var report in reports) + { + var num = report.Value.Keys.Max(x => x); + report.Value.Add(num + 1, "Резерв"); + report.Value.Add(num + 2, "Резерв"); + } + + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + var reps = GetReports(new int?()); + if (reports.Any(x => !x.Value.ContainsKey(0))) + { + command.CommandText = + "UPDATE Report SET Report = @Report WHERE CategoryID = @CategoryID AND ReportNo <> 0"; + foreach (var report in reports) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@CategoryID", report.Key); + command.Parameters.AddWithValue("@Report", "Резерв"); + command.ExecuteNonQuery(); + } + } + + command.CommandText = + "UPDATE Report SET Report = @Report WHERE CategoryID = @CategoryID AND ReportNo = @ReportNo"; + foreach (var report in reports) + { + var r1 = report; + var source = r1.Value; + foreach (var keyValuePair in source.Where(x => + reps.ContainsKey(new Tuple(r1.Key, x.Key)))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@CategoryID", r1.Key); + command.Parameters.AddWithValue("@ReportNo", keyValuePair.Key); + command.Parameters.AddWithValue("@Report", keyValuePair.Value); + command.ExecuteNonQuery(); + } + } + + command.CommandText = "INSERT OR REPLACE INTO Report VALUES(@CategoryID, @ReportNo, @URL, @Report)"; + foreach (var report in reports) + { + var r1 = report; + var source = r1.Value; + foreach (var keyValuePair in source.Where(x => + !reps.ContainsKey(new Tuple(r1.Key, x.Key)))) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@CategoryID", r1.Key); + command.Parameters.AddWithValue("@ReportNo", keyValuePair.Key); + command.Parameters.AddWithValue("@URL", string.Empty); + command.Parameters.AddWithValue("@Report", keyValuePair.Value); + command.ExecuteNonQuery(); + } + } + } + + sqLiteTransaction.Commit(); + } + } + + public Dictionary, Tuple> GetReports(int? categoryId = null) + { + var dictionary = + new Dictionary, Tuple>(); + using (var command = _conn.CreateCommand()) + { + command.CommandText = "SELECT * FROM Report"; + if (categoryId.HasValue) + { + command.CommandText += " WHERE CategoryID = @CategoryID"; + command.Parameters.AddWithValue("@CategoryID", categoryId.Value); + } + + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + if (!dictionary.ContainsKey(new Tuple(sqLiteDataReader.GetInt32(0), + sqLiteDataReader.GetInt32(1)))) + dictionary.Add( + new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetInt32(1)), + new Tuple(sqLiteDataReader.GetString(2), + sqLiteDataReader.GetString(3))); + } + } + + return dictionary; + } + + public void SaveSettingsReport(List> result) + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + command.CommandText = "SELECT DISTINCT CategoryID FROM Report WHERE ReportNo = 0"; + var filter = new HashSet(); + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + filter.Add(sqLiteDataReader.GetInt32(0)); + } + + command.CommandText = + "UPDATE Report SET URL = @url WHERE CategoryID = @CategoryID AND ReportNo = @ReportNo"; + command.Parameters.Add("@CategoryID", DbType.Int32); + command.Parameters.Add("@ReportNo", DbType.Int32); + command.Parameters.Add("@url", DbType.String); + command.Prepare(); + foreach (var tuple in result) + { + command.Parameters["@CategoryID"].Value = tuple.Item1; + command.Parameters["@ReportNo"].Value = tuple.Item2; + command.Parameters["@url"].Value = tuple.Item3; + command.ExecuteNonQuery(); + } + + command.CommandText = "INSERT OR REPLACE INTO Report VALUES(@CategoryID, @ReportNo, @URL, '')"; + command.Prepare(); + var source = result; + foreach (var tuple in source.Where(x => !filter.Contains(x.Item1))) + { + command.Parameters["@CategoryID"].Value = tuple.Item1; + command.Parameters["@ReportNo"].Value = tuple.Item2; + command.Parameters["@url"].Value = tuple.Item3; + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public void UpdateStatistics() + { + using (var sqLiteTransaction = _conn.BeginTransaction()) + { + using (var command = _conn.CreateCommand()) + { + command.Transaction = sqLiteTransaction; + var numArrayList = new List(); + command.CommandText = + "update Topic SET AvgSeeders = (SELECT AVG(Seeders) FROM TopicStatusHystory AS st WHERE st.TopicID = Topic.TopicID)"; + command.ExecuteNonQuery(); + command.CommandText = "UPDATE Topic SET AvgSeeders = @Seeders WHERE TopicID = @TopicID"; + foreach (var numArray in numArrayList) + { + command.Parameters.Clear(); + command.Parameters.AddWithValue("@TopicID", numArray[0]); + command.Parameters.AddWithValue("@Seeders", numArray[1]); + command.ExecuteNonQuery(); + } + } + + sqLiteTransaction.Commit(); + } + } + + public void ClearKeepers() + { + using (var command = _conn.CreateCommand()) + { + command.CommandText = + @" + DELETE FROM Keeper; + DELETE FROM KeeperToTopic; + UPDATE Report SET Report = '' WHERE ReportNo = 0"; + command.ExecuteNonQuery(); + } + } + } +} \ No newline at end of file diff --git a/TLO/Clients/DbConnectionCreator.cs b/TLO/Clients/DbConnectionCreator.cs new file mode 100644 index 0000000..eb37da3 --- /dev/null +++ b/TLO/Clients/DbConnectionCreator.cs @@ -0,0 +1,92 @@ +using System.Data.SQLite; +using NLog; + +namespace TLO.Clients +{ + public class DbConnectionCreator + { + private DbConnectionCreator() + { + if (Logger == null) + Logger = LogManager.GetLogger("SQLite"); + + var db = $"Data Source={ClientLocalDb.FileDatabase};Version=3;"; + if (InMemory()) + { + _internalConnection = new SQLiteConnection(db); + _internalConnection.Open(); + Connection = new SQLiteConnection("Data Source=:memory:;Version=3;"); + Connection.Open(); + Logger.Info("Загрузка базы в память..."); + _internalConnection.BackupDatabase(Connection, "main", "main", -1, null, -1); + Logger.Info("Загрузка базы в память завершена."); + } + else + { + Logger.Info("Подключение к файлу бд..."); + _internalConnection = new SQLiteConnection(db); + _internalConnection.Open(); + Connection = _internalConnection; + } + } + + public void Persist() + { + if (_inMemory) + { + Logger.Info("Сохранение базы в файл из памяти..."); + var command = Connection.CreateCommand(); + command.CommandText = "VACUUM \"main\";"; + command.ExecuteNonQuery(); + Connection.BackupDatabase(_internalConnection, "main", "main", -1, null, -1); + Logger.Info("Сохранение завершено."); + } + } + + public bool Reconnect() + { + bool configChanged = _inMemory != InMemory(); + if (configChanged) + { + if (_inMemory) + { + Persist(); + // Почистим инстанс, если конфигурация изменилась. + _internalConnection.Close(); + Connection.Close(); + _instance = null; + + return true; + } + else + { + _internalConnection.Close(); + // Почистим инстанс, так как конфигурация изменилась. + _instance = null; + return true; + } + } + + return false; + } + + private static DbConnectionCreator _instance; + public static DbConnectionCreator Instance => _instance ??= new DbConnectionCreator(); + + private readonly bool _inMemory = InMemory(); + private readonly SQLiteConnection _internalConnection; + public SQLiteConnection Connection { get; } + + private static Logger? Logger { get; set; } + + public void Close() + { + Connection.Close(); + } + + private static bool InMemory() + { + return Settings.Current.LoadDBInMemory.GetValueOrDefault(true); + } + } +} \ No newline at end of file diff --git a/TLO/Clients/ITorrentClient.cs b/TLO/Clients/ITorrentClient.cs new file mode 100644 index 0000000..723ba9f --- /dev/null +++ b/TLO/Clients/ITorrentClient.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using TLO.Info; + +namespace TLO.Clients +{ + internal interface ITorrentClient + { + string Id { get; } + + List GetAllTorrentHash(); + + IEnumerable GetFiles(TopicInfo topic); + + void DistributionStop(IEnumerable data); + + void DistributionPause(IEnumerable data); + + void DistributionStart(IEnumerable data); + + bool Ping(); + + bool SetDefaultFolder(string dir); + + bool SetDefaultLabel(string label); + + string GetDefaultFolder(); + + void SendTorrentFile(string path, string file); + + void SendTorrentFile(string path, string filename, byte[] fdata); + + string[] GetTrackers(string hash); + + bool SetTrackers(string hash, string[] trackers); + + bool SetLabel(string hash, string label); + + bool SetLabel(IEnumerable hash, string label); + } +} \ No newline at end of file diff --git a/TLO/Clients/QBitTorrentClient.cs b/TLO/Clients/QBitTorrentClient.cs new file mode 100644 index 0000000..95ade9f --- /dev/null +++ b/TLO/Clients/QBitTorrentClient.cs @@ -0,0 +1,311 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Web.Caching; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class QBitTorrentClient : ITorrentClient + { + public const string ClientId = "QBitTorrent"; + public string Id => ClientId; + private readonly TloWebClient _client; + private readonly Uri _baseUri; + private readonly UriTemplate _uriTemplate; + private readonly string _host; + private readonly int _port; + private readonly string _username; + private readonly string _password; + private readonly Logger Logger = LogManager.GetLogger("QBitTorrentClient"); + + public QBitTorrentClient(string host, int port, string username, string password) + { + _baseUri = new Uri($"http://{host}:{port}/"); + _uriTemplate = new UriTemplate("api/v2/{section}/{methodName}"); + _client = new TloWebClient(Encoding.UTF8, "TLO", "text/*,application/*", true); + _host = host; + _port = port; + _username = username; + _password = password; + _client.Headers.Add("Referer", _baseUri.ToString()); + _client.UseDefaultCredentials = true; + + // if (this.Ping()) + // { + // authorize(); + // } + } + + private void authorize() + { + try + { + var auth = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "auth"}, {"methodName", "login"} + }); + + var builder = new UriBuilder(auth); + builder.Query = $"username={_username}&password={_password}"; + var result = _client.DownloadString(builder.Uri); + Logger.Log(LogLevel.Debug, "Auth: " + result); + } + catch (WebException e) + { + Logger.Error(e); + Logger.Error(e.StackTrace); + } + } + + public List GetAllTorrentHash() + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "info"} + }); + string result; + try + { + result = _client.DownloadString(uri); + } + catch (WebException e) + { + Logger.Error(e); + Logger.Error(e.StackTrace); + + throw e; + } + + try + { + var torrents = JsonConvert.DeserializeObject>(result); + return torrents.ConvertAll(input => + { + var info = new TopicInfo(); + info.Hash = input.GetValue("hash").ToString().ToUpper(); + info.Name2 = input.GetValue("name").ToString(); + info.TorrentName = input.GetValue("name").ToString(); + info.Size = (long) input.GetValue("size").ToObject(typeof(long)); + info.Seeders = (int) input.GetValue("num_complete").ToObject(typeof(int)); + info.Leechers = (int) input.GetValue("num_incomplete").ToObject(typeof(int)); + info.Label = (string) input.GetValue("tags").ToObject(typeof(string)); + info.IsRun = input.GetValue("state").ToString() == "stalledUP"; + info.IsKeep = input.GetValue("state").ToString().Contains("UP") || "uploading" == input.GetValue("state").ToString(); + info.IsPause = input.GetValue("state").ToString() == "pausedUP" || + input.GetValue("state").ToString() == "pausedDL"; + info.IsDownload = input.GetValue("state").ToString() == "downloading" || input.GetValue("state").ToString().EndsWith("DL"); + return info; + } + ); + } + catch (Exception e) + { + Logger.Error(e); + Logger.Error(e.StackTrace); + + throw e; + } + } + + public IEnumerable GetFiles(TopicInfo topic) + { + return new string[0]; // TODO + throw new NotImplementedException(); + } + + public void DistributionStop(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public void DistributionPause(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public void DistributionStart(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public bool Ping() + { + try + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "app"}, {"methodName", "version"} + }); + Logger.Debug("Version: " + _client.DownloadString(uri)); + + return true; + } + catch(Exception e) + { + System.Console.WriteLine(e.Message); + return false; + } + } + + public bool SetDefaultFolder(string dir) + { + return true; // TODO + throw new NotImplementedException(); + } + + public bool SetDefaultLabel(string label) + { + return true; // TODO + throw new NotImplementedException(); + } + + public string GetDefaultFolder() + { + return ""; // TODO + throw new NotImplementedException(); + } + + public void SendTorrentFile(string path, string file) + { + return; // TODO + throw new NotImplementedException(); + } + + public void SendTorrentFile(string path, string filename, byte[] fdata) + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "add"} + }); + + var str = "----WebKitFormBoundary1vZaMilolI9TchBt"; + using (var memoryStream = new MemoryStream()) + { + var bytes0 = Encoding.UTF8.GetBytes( + $"--{str}\r\nContent-Disposition: form-data; name=\"savepath\"\r\n\r\n{path}"); + var bytes1 = Encoding.UTF8.GetBytes( + $"--{str}\r\nContent-Disposition: form-data; name=\"torrent_file\"; filename=\"{filename}\"\r\nContent-Type: application/x-bittorrent\r\n\r\n"); + memoryStream.Write(bytes0, 0, bytes0.Length); + memoryStream.Write(bytes1, 0, bytes1.Length); + memoryStream.Write(fdata, 0, fdata.Length); + var bytes2 = Encoding.UTF8.GetBytes($"\r\n--{str}--\r\n"); + memoryStream.Write(bytes2, 0, bytes2.Length); + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Method = "POST"; + httpWebRequest.KeepAlive = true; + httpWebRequest.ContentType = "multipart/form-data; boundary=" + str; + httpWebRequest.CookieContainer = _client.CookieContainer; + var array = memoryStream.ToArray(); + httpWebRequest.ContentLength = array.Length; + using (var requestStream = httpWebRequest.GetRequestStream()) + { + requestStream.Write(array, 0, array.Length); + requestStream.Flush(); + requestStream.Close(); + } + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + reader.ReadToEnd(); + reader.Close(); + } + } + + public string[] GetTrackers(string hash) + { + return new string[0]; // TODO + throw new NotImplementedException(); + } + + public bool SetTrackers(string hash, string[] trackers) + { + return true; // TODO + throw new NotImplementedException(); + } + + public bool SetLabel(string hash, string label) + { + try + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "addTags"} + }); + var data = $"hashes={hash.ToLower()}&tags={WebUtility.UrlEncode(label.Replace(",", "‚"))}"; + var bytes = Encoding.UTF8.GetBytes(data); + + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Method = "POST"; + httpWebRequest.ContentType = "application/x-www-form-urlencoded"; + httpWebRequest.CookieContainer = _client.CookieContainer; + httpWebRequest.ContentLength = bytes.Length; + var stream = httpWebRequest.GetRequestStream(); + stream.Write(bytes, 0, bytes.Length); + stream.Flush(); + stream.Close(); + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + reader.ReadToEnd(); + reader.Close(); + return true; + } + catch (WebException e) + { + Logger.Error(e.Message); + Logger.Error(e.StackTrace); + return false; + } + } + + public bool SetLabel(IEnumerable hash, string label) + { + try + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "addTags"} + }); + var data = + $"hashes={string.Join("|", hash.ToList().ConvertAll((input => input.ToLower())))}&tags={WebUtility.UrlEncode(label.Replace(",", "‚"))}"; + var bytes = Encoding.UTF8.GetBytes(data); + + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Method = "POST"; + httpWebRequest.ContentType = "application/x-www-form-urlencoded"; + httpWebRequest.CookieContainer = _client.CookieContainer; + httpWebRequest.ContentLength = bytes.Length; + var stream = httpWebRequest.GetRequestStream(); + stream.Write(bytes, 0, bytes.Length); + stream.Flush(); + stream.Close(); + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + reader.ReadToEnd(); + reader.Close(); + + return true; + } + catch (WebException e) + { + Logger.Error(e.Message); + Logger.Error(e.StackTrace); + return false; + } + } + } +} \ No newline at end of file diff --git a/TLO/Clients/RuTrackerOrg.cs b/TLO/Clients/RuTrackerOrg.cs new file mode 100644 index 0000000..a1fd69c --- /dev/null +++ b/TLO/Clients/RuTrackerOrg.cs @@ -0,0 +1,781 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Web; +using System.Windows.Forms; +using AngleSharp.Dom; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class RuTrackerOrg + { + private static RuTrackerOrg? _current; + private readonly Logger _logger; + private readonly string _userName; + private readonly string _userPass; + private string _apiId; + private JsonSerializer _jSerializer; + private int _keeperId; + private TloWebClient _webClient; + + public RuTrackerOrg(string userName, string password) + { + _jSerializer = new JsonSerializer(); + _userName = userName; + _userPass = password; + if (_logger == null) _logger = LogManager.GetLogger("RuTrackerOrg"); + if (string.IsNullOrWhiteSpace(_userName) || string.IsNullOrWhiteSpace(_userPass)) return; + + ReadKeeperInfo(); + } + + public static RuTrackerOrg Current => + _current ??= new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass); + + public IEnumerable GetCategories() + { + var source = new List(); + var downloadArchivePage = + DownloadArchivePage($"https://{Settings.Current.ApiHost}/v1/static/cat_forum_tree"); + var jObject1 = (JsonConvert.DeserializeObject(downloadArchivePage) as JObject)["result"] + .ToObject(); + jObject1["c"].ToObject(); + source.AddRange(jObject1["c"].ToObject>().Select(x => new Category + { + CategoryID = 1000000 + int.Parse(x.Key), + Name = x.Value as string + }).ToArray()); + source.AddRange(jObject1["f"].ToObject>().Select(x => new Category + { + CategoryID = int.Parse(x.Key), + Name = x.Value as string + })); + var dictionary = source.ToDictionary(x => x.CategoryID, x => x); + var jObject2 = jObject1["tree"].ToObject(); + var num = 0; + foreach (var keyValuePair1 in jObject2) + { + var key1 = int.Parse(keyValuePair1.Key) + 1000000; + ++num; + dictionary[key1].OrderID = num; + dictionary[key1].FullName = dictionary[key1].Name; + if (!(keyValuePair1.Value is JObject) || !keyValuePair1.Value.Any()) continue; + + foreach (var keyValuePair2 in keyValuePair1.Value.ToObject()) + { + var key2 = int.Parse(keyValuePair2.Key); + ++num; + if (dictionary.ContainsKey(key2)) + { + var category = dictionary[key2]; + category.ParentID = key1; + category.OrderID = num; + category.FullName = + $"{(dictionary.ContainsKey(key1) ? dictionary[key1].Name : "")} » {category.Name}"; + } + + foreach (var jToken in keyValuePair2.Value.ToObject()) + { + var key3 = (int) jToken; + ++num; + if (dictionary.ContainsKey(key3)) + { + var category = dictionary[key3]; + category.ParentID = key2; + category.OrderID = num; + category.FullName = + $"{(dictionary.ContainsKey(key2) ? dictionary[key2].FullName : "")} » {category.Name}"; + } + } + } + } + + return source; + } + + public IEnumerable> GetCategoriesFromPost(string postUrl) + { + var tupleList = new List>(); + var array = DownloadWebPage(postUrl).Split(new char[2] + { + '\r', + '\n' + }, StringSplitOptions.RemoveEmptyEntries).Where(x => + { + if (x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=")) + return x.Contains("class=\"postLink\""); + return false; + }).ToArray(); + var nullable1 = new int?(); + string str1 = null; + foreach (var str2 in array) + { + var separator = new[] {'"', '<', '>', ' '}; + var num1 = 1; + foreach (var postUrl1 in str2.Split(separator, (StringSplitOptions) num1).Where(x => + { + if (!x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=") && + !x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) + return x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p="); + return true; + }).ToArray()) + { + if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=")) + nullable1 = int.Parse( + postUrl1.Replace($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewforum.php?f=", + "")); + var nullable2 = nullable1; + var num2 = 2020; + if ((nullable2.GetValueOrDefault() == num2 ? nullable2.HasValue ? 1 : 0 : 0) != 0) + Console.Write(""); + if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=") && + postUrl1 != $"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=") + str1 = postUrl1; + if (postUrl1.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p=")) + str1 = GetTopicUrlByPostUrl(postUrl1); + } + + if (nullable1.HasValue && !string.IsNullOrWhiteSpace(str1)) + tupleList.Add(new Tuple(nullable1.Value, str1)); + nullable1 = new int?(); + str1 = null; + } + + return tupleList; + } + + public string GetTopicUrlByPostUrl(string postUrl) + { + var str = DownloadWebPage(postUrl); + if (str.Contains("
Тема не найдена
")) + return null; + return str.Split(new char[1] + { + '"' + }, StringSplitOptions.RemoveEmptyEntries) + .Where(x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) + .Select(x => x).FirstOrDefault(); + } + + public int[][] GetTopicsStatus(int forumId) + { + var dictionary = + JsonConvert.DeserializeObject(DownloadArchivePage( + string.Format("https://{1}/v1/static/pvc/f/{0}", forumId, Settings.Current.ApiHost)))["result"] + .ToObject>(); + var numArray1 = new int[dictionary.Count][]; + var index = 0; + foreach (var keyValuePair in dictionary) + { + var numArray2 = keyValuePair.Value; + numArray1[index] = new int[2] + { + keyValuePair.Key, + numArray2.Length > 1 ? Convert.ToInt32(numArray2[1]) : -1 + }; + ++index; + } + + return numArray1; + } + + public List GetTopicsInfo(int[] topics) + { + if (topics == null || topics.Length == 0 || topics.Length > 100) + return null; + var topicInfoList = new List(); + foreach (var keyValuePair in + JsonConvert.DeserializeObject(DownloadArchivePage(string.Format( + "https://{0}/v1/get_tor_topic_data?by=topic_id&val={1}", Settings.Current.ApiHost, + HttpUtility.UrlEncode(string.Join(",", topics)))))["result"] + .ToObject>>()) + { + var topicInfo = new TopicInfo(); + topicInfo.TopicID = keyValuePair.Key; + var dictionary = keyValuePair.Value; + if (dictionary != null) + { + topicInfo.Hash = dictionary["info_hash"] as string; + topicInfo.CategoryID = int.Parse(dictionary["forum_id"].ToString()); + topicInfo.RegTime = + new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(int.Parse(dictionary["reg_time"].ToString())); + topicInfo.Size = long.Parse(dictionary["size"].ToString()); + topicInfo.Status = int.Parse(dictionary["tor_status"].ToString()); + topicInfo.Seeders = int.Parse(dictionary["seeders"].ToString()); + topicInfo.Name2 = dictionary["topic_title"] as string; + topicInfo.PosterID = int.Parse(dictionary["poster_id"].ToString()); + } + + topicInfoList.Add(topicInfo); + } + + Thread.Sleep(500); + return topicInfoList; + } + + public IEnumerable GetUsers(int[] id) + { + if (id == null || !id.Any()) + return null; + var bulkSize = 50; + var userInfoList = new List(); + var intListArray = new List[id.Count() % bulkSize == 0 ? id.Count() / bulkSize : id.Count() / bulkSize + 1]; + for (var index1 = 0; index1 < id.Count(); ++index1) + { + var index2 = index1 / bulkSize; + if (intListArray[index2] == null) + intListArray[index2] = new List(); + intListArray[index2].Add(id[index1]); + } + + foreach (IEnumerable values in intListArray) + { + var url = string.Format("https://{0}/v1/get_user_name?by=user_id&val={1}", Settings.Current.ApiHost, + HttpUtility.UrlEncode(string.Join(",", values))); + var getUserNameResult = DownloadArchivePage(url); + foreach (var keyValuePair in + JsonConvert.DeserializeObject(getUserNameResult)["result"] + .ToObject>()) + userInfoList.Add(new UserInfo + { + UserID = keyValuePair.Key, + Name = keyValuePair.Value + }); + Thread.Sleep(500); + } + + return userInfoList; + } + + private List GetPostsFromTopicId(int topicId) + { + var num1 = 0; + var intList = new List(); + string str1; + do + { + str1 = DownloadWebPage(string.Format("https://{2}/forum/viewtopic.php?t={0}{1}", topicId, + num1 == 0 ? "" : "&start=" + num1, Settings.Current.HostRuTrackerOrg)); + if (str1.Contains("
Тема не найдена
")) + { + Thread.Sleep(500); + str1 = DownloadWebPage(string.Format("https://{0}/forum/viewtopic.php?p={1}", topicId, + Settings.Current.HostRuTrackerOrg)); + if (str1.Contains("
Тема не найдена
")) + return new List(); + var s = str1.Split(new char[1] + { + '"' + }, StringSplitOptions.RemoveEmptyEntries) + .Where(x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) + .Select(x => x.Replace("https://rutracker.org/forum/viewtopic.php?t=", "")).FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(s)) + { + topicId = int.Parse(s); + goto label_13; + } + } + + var str2 = str1; + var separator1 = new char[2] {'\r', '\n'}; + var num2 = 1; + foreach (var str3 in str2.Split(separator1, (StringSplitOptions) num2) + .Where(x => x.Contains("\">[Цитировать]")).ToArray()) + { + var separator2 = new char[1] {'"'}; + var num3 = 1; + var str4 = str3.Split(separator2, (StringSplitOptions) num3) + .FirstOrDefault(x => x.Contains("https://")); + if (!string.IsNullOrWhiteSpace(str4)) + { + var strArray = str4.Split('='); + if (strArray.Length >= 3) + intList.Add(int.Parse(strArray[2])); + } + } + + num1 += 30; + label_13: ; + } while (str1.Contains("\">След.

") || num1 == 0); + + return intList; + } + + private Tuple> GetTopicsFromReport(int postId, int categoryId) + { + Tuple> tuple = null; + var strArray1 = DownloadWebPage(string.Format("https://post.{1}/forum/posting.php?mode=quote&p={0}", + postId, Settings.Current.HostRuTrackerOrg)).Split(new string[2] + { + "" + }, StringSplitOptions.RemoveEmptyEntries); + if (strArray1.Length < 2) + return tuple; + var str1 = strArray1[1]; + var separator = new char[2] {'[', ']'}; + var num = 1; + foreach (var str2 in str1 + .Split(separator, (StringSplitOptions) num) + .Where(x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=") || + x.Contains("quote=")).ToArray()) + try + { + if (str2.Contains("quote=")) + { + tuple = new Tuple>(str2.Replace("quote=", "").Replace("\"", ""), + categoryId, new List()); + } + else if (tuple != null) + { + var strArray2 = str2.Split('='); + if (strArray2.Length >= 3) + tuple.Item3.Add(int.Parse(strArray2[2])); + } + } + catch (Exception ex) + { + _logger.Error("Ошибка получения информации о раздаче по адресу \"" + str2 + "\": " + ex.Message); + _logger.Warn(ex.StackTrace); + _logger.Debug(ex); + } + + return tuple; + } + + public Dictionary>> GetKeeps(int topicid, int categoryId) + { + Dictionary>> dictionary; + dictionary = new Dictionary>>(); + var empty = string.Empty; + var num = 0; + + var parser = new AngleSharp.Html.Parser.HtmlParser(); + string str1; + do + { + label_18: + var _url = string.Format("https://{2}/forum/viewtopic.php?t={0}{1}", + topicid, num == 0 ? "" : "&start=" + num, Settings.Current.HostRuTrackerOrg); + str1 = DownloadWebPage(_url); + if (str1.Contains("
Тема не найдена
")) + { + Thread.Sleep(500); + str1 = DownloadWebPage( + $"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?p={(object) topicid}"); + if (str1.Contains("
Тема не найдена
")) + { + MessageBox.Show("Тема не найдена, или неправильно указана ссылка на раздел: " + _url, "Ошибка", + icon: MessageBoxIcon.Warning, buttons: MessageBoxButtons.OK); + return dictionary; + } + var s = string.Join("\r\n", str1.Split('\r', '\n').Where(x => x.Contains("id=\"topic-title\""))) + .Split(new char[4] + { + '"', + '<', + '>', + ' ' + }, StringSplitOptions.RemoveEmptyEntries) + .Where(x => x.Contains($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=")) + .Select(x => + x.Replace($"https://{Settings.Current.HostRuTrackerOrg}/forum/viewtopic.php?t=", "")) + .FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(s)) + { + topicid = int.Parse(s); + goto label_18; + } + } + + var document = parser.ParseDocument(str1); + var posts = document.QuerySelectorAll("table#topic_main > tbody"); + foreach (var post in posts) + { + if (!post.ClassList.Contains("row1") && !post.ClassList.Contains("row2")) + { + continue; + } + + var keeperName = post.QuerySelector("td.poster_info > p.nick > a").Text().Trim(); + if (!dictionary.ContainsKey(keeperName)) + { + dictionary.Add(keeperName, new Tuple>(categoryId, new List())); + } + + var links = post.QuerySelectorAll("td.message div.post_body a"); + foreach (var link in links) + { + var url = link.GetAttribute("href").Trim(); + var match = new Regex(@"viewtopic.php\?t=([0-9]+)$").Match(url); + if (!match.Success) + { + continue; + } + + + var topicId = match.Groups[1].Value; + try + { + dictionary[keeperName].Item2.Add(int.Parse(topicId)); + } + catch (Exception ex) + { + _logger.Warn(topicid + "\t" + topicId + "\t" + ex.Message); + } + } + } + + num += 30; + } while (str1.Contains("\">След.

") || num == 0); + + return dictionary; + } + + public Dictionary>> GetKeeps2(int topicid, int categoryId) + { + var dictionary = new Dictionary>>(); + foreach (var postId in GetPostsFromTopicId(topicid)) + { + var topicsFromReport = GetTopicsFromReport(postId, categoryId); + if (topicsFromReport != null && topicsFromReport.Item3.Count != 0) + { + if (!dictionary.ContainsKey(topicsFromReport.Item1)) + dictionary.Add(topicsFromReport.Item1, + new Tuple>(topicsFromReport.Item2, new List())); + dictionary[topicsFromReport.Item1].Item2.AddRange(topicsFromReport.Item3); + } + } + + return dictionary; + } + + private string DownloadArchivePage(string page) + { + var tloWebClient = new TloWebClient(enableProxy: true); + return tloWebClient.DownloadString(page); + } + + public string DownloadWebPage(string page, params object[] param) + { + return Encoding.GetEncoding("windows-1251").GetString(DownloadWebPages(string.Format(page, param))); + } + + public byte[] DownloadTorrentFile(int id) + { + for (var index = 0; index < 100; ++index) + { + var numArray1 = new byte[0]; + var empty = string.Empty; + TloWebClient tloWebClient = null; + try + { + if (_webClient == null) + { + tloWebClient = new TloWebClient(enableProxy: true); + var s = string.Format("login_username={0}&login_password={1}&login={2}", + HttpUtility.UrlEncode(_userName, Encoding.GetEncoding(1251)), + HttpUtility.UrlEncode(_userPass, Encoding.GetEncoding(1251)), "Вход"); + empty = Encoding.GetEncoding("windows-1251").GetString( + tloWebClient.UploadData("https://" + Settings.Current.HostRuTrackerOrg + "/forum/login.php", + "POST", Encoding.GetEncoding(1251).GetBytes(s))); + Thread.Sleep(500); + } + } + catch (Exception ex) + { + _logger.Warn(ex.Message); + _logger.Warn(ex); + _logger.Trace(ex.StackTrace); + } + + if (!string.IsNullOrWhiteSpace(empty)) + { + if (empty.Contains("https://static." + Settings.Current.HostRuTrackerOrg + "/captcha")) + throw new Exception( + "При авторизации требуется ввести текст с картинки. Авторизуйтесь на WEB-сайте, а потом повторите попытку"); + if (empty.Contains("Регистрация")) + throw new Exception("Не удалось авторизоваться, проверьте логин и пароль"); + _webClient = tloWebClient; + } + + byte[] numArray2; + if (string.IsNullOrWhiteSpace(_apiId)) + { + var str = + DownloadWebPage(string.Format( + "https://" + Settings.Current.HostRuTrackerOrg + "/forum/viewtopic.php?t={0}", id)) + .Split(new char[2] + { + '\r', + '\n' + }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.Contains("form_token: '")) + .FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(str)) + str = str.Split(new char[1] {'\''}, StringSplitOptions.RemoveEmptyEntries)[1]; + var s = string.Format("form_token={0}", str); + numArray2 = _webClient.UploadData( + string.Format("https://" + Settings.Current.HostRuTrackerOrg + "/forum/dl.php?t={0}", + id), "POST", Encoding.GetEncoding(1251).GetBytes(s)); + } + else + { + numArray2 = _webClient.UploadData( + "https://" + Settings.Current.HostRuTrackerOrg + "/forum/dl.php", "POST", + Encoding.GetEncoding(1251).GetBytes(string.Format( + "keeper_user_id={0}&keeper_api_key={1}&t={2}&add_retracker_url=0", _keeperId, _apiId, + id))); + } + + var lower = Encoding.GetEncoding(1251).GetString(numArray2).ToLower(); + if (lower.ToLower().Contains("форум временно отключен") || lower.Contains("форум временно отключен")) + throw new Exception("Форум временно отключен"); + if (lower.Contains("https://static." + Settings.Current.HostRuTrackerOrg + "/captcha") || + lower.Contains("регистрация")) + { + if (_webClient != null) + _webClient.Dispose(); + _webClient = null; + } + else + { + if (lower[0] == 'd') + return numArray2; + var path = Path.Combine(Settings.Folder, "error_" + id + ".html"); + if (File.Exists(path)) + File.Delete(path); + using (var fileStream = File.Create(path)) + { + fileStream.Write(numArray2, 0, numArray2.Length); + } + + return null; + } + } + + return null; + } + + public byte[] DownloadWebPages(string page) + { + for (var index = 0; index < 1; ++index) + { + var empty = string.Empty; + TloWebClient tloWebClient = null; + try + { + if (_webClient == null) + { + tloWebClient = new TloWebClient(Encoding.GetEncoding(1251)); + if (!string.IsNullOrWhiteSpace(_userName) && !string.IsNullOrWhiteSpace(_userPass)) + { + var s = string.Format("login_username={0}&login_password={1}&login={2}", + HttpUtility.UrlEncode(_userName, Encoding.GetEncoding(1251)), + HttpUtility.UrlEncode(_userPass, Encoding.GetEncoding(1251)), "вход"); + empty = Encoding.GetEncoding("windows-1251").GetString( + tloWebClient.UploadData( + $"https://{Settings.Current.HostRuTrackerOrg}/forum/login.php".Replace( + "rutracker.org", Settings.Current.HostRuTrackerOrg), "POST", + Encoding.GetEncoding(1251).GetBytes(s))); + } + + Thread.Sleep(500); + } + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Error(ex.StackTrace); + _logger.Error(ex); + } + + if (!string.IsNullOrWhiteSpace(empty) && !string.IsNullOrWhiteSpace(_userName) && + !string.IsNullOrWhiteSpace(_userPass)) + { + if (empty.Contains( + $"https://static.{Settings.Current.HostRuTrackerOrg}/captcha".Replace("rutracker.org", + Settings.Current.HostRuTrackerOrg))) + throw new Exception( + "При авторизации требуется ввести текст с картинки. Авторизуйтесь на WEB-сайте, а потом повторите попытку"); + if (empty.Contains("Регистрация")) + throw new Exception("Не удалось авторизоваться, проверьте логин и пароль"); + _webClient = tloWebClient; + } + + byte[] bytes; + try + { + bytes = _webClient.DownloadData(page); + } + catch (Exception e) + { + _logger.Error(e); + _logger.Error(e.StackTrace); + continue; + } + + var str = Encoding.GetEncoding("windows-1251").GetString(bytes); + if (str.ToLower().Contains("форум временно отключен") || + str.ToLower().Contains("форум временно отключен")) + throw new Exception("Форум временно отключен"); + if (!str.Contains( + $"https://static.{Settings.Current.HostRuTrackerOrg}/captcha".Replace("rutracker.org", + Settings.Current.HostRuTrackerOrg)) && + !str.Contains("Регистрация")) + return bytes; + if (_webClient != null) + _webClient.Dispose(); + _webClient = null; + } + + throw new Exception("Не удалось скачать WEB-страницу за 1 попытку"); + } + + public byte[] DownloadArchiveData(string page) + { + for (var index = 0; index < 1; ++index) + { + var numArray = new byte[0]; + var empty = string.Empty; + if (_webClient == null) + _webClient = new TloWebClient(enableProxy: true); + byte[] bytes; + try + { + bytes = _webClient.DownloadData(page); + } + catch + { + Thread.Sleep(index * 200); + continue; + } + + var lower = Encoding.GetEncoding(1251).GetString(bytes).ToLower(); + if (lower.Contains("введите ваше имя и пароль")) + return new byte[0]; + if (lower.ToLower().Contains("форум временно отключен") || lower.Contains("введите ваше имя и пароль")) + throw new Exception("Форум временно отключен"); + if (lower[0] != 'd') + return new byte[0]; + return bytes; + } + + throw new Exception("Не удалось скачать WEB-страницу за 1 попытку"); + } + + public void SavePage(string topicId, string folder) + { + var str = + new TloWebClient(enableProxy: true).DownloadString(string.Format( + "https://rutracker.org/forum/viewtopic.php?t={0}", + topicId)); + if (str.Contains("Тема не найдена")) + return; + using (var fileStream = File.Create(Path.Combine(folder, string.Format("{0}.html", topicId)))) + { + using (var streamWriter = new StreamWriter(fileStream, Encoding.GetEncoding(1251))) + { + streamWriter.Write(str); + } + } + } + + public void SendReport(string url, string message) + { + if (url.Split('#').FirstOrDefault().Split('=').Length < 3) + throw new ArgumentException("Не корректно указан адрес отправки отчета: " + url); + var str1 = url.Split('#').FirstOrDefault().Split('=')[2]; + var page = string.Format("https://{1}/forum/posting.php?mode=editpost&p={0}", str1, + Settings.Current.HostRuTrackerOrg); + var strArray = DownloadWebPage(page).Split(new char[2] + { + '\r', + '\n' + }, StringSplitOptions.RemoveEmptyEntries); + Thread.Sleep(200); +// string.Format("align=-1&codeColor=black&codeSize=12&codeUrl2=&decflag=2&f=1584&fontFace=-1&form_token=c2a9bace5d7f3900e2bddbf5f0f0f94a&message=&mode=editpost&p=59972538&submit_mode=submit&t=3985106"); + var str3 = strArray.Where(x => x.Contains("form_token: '")).FirstOrDefault(); + if (string.IsNullOrWhiteSpace(str3)) + throw new ArgumentException("Параметр 'form_token' не найден на странице"); + var str4 = strArray.Where(x => x.Contains("name=\"t\" value=\"")).FirstOrDefault(); + if (string.IsNullOrWhiteSpace(str4)) + throw new ArgumentException($"Параметр 't' не найден на странице '{page}'"); + if (str4.Split('"').Length < 6) + throw new ArgumentException($"Массив с параметром 't' на странице '{page}' меньше предполагаемого: " + + str4); + if (str3.Split('\'').Length < 2) + throw new ArgumentException("Массив с параметром 'form_token' меньше предполагаемого: " + str3); + var str5 = strArray.Where(x => x.Contains("name=\"subject\" ")).FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(str5)) + if (str5.Split('"').Length < 12) + throw new ArgumentException("Массив с параметром 'subject' меньше предполагаемого: " + str5); + + var _params = new NameValueCollection(); + _params.Add("t", str4.Split('"')[5]); + _params.Add("submit_mode", "submit"); + _params.Add("form_token", str3.Split('\'')[1]); + _params.Add("message", message); + if (!string.IsNullOrWhiteSpace(str5)) + _params.Add("subject", str5.Split('"')[11]); + for (var index2 = 0; index2 < 1;) + try + { + var _url = string.Format("https://{0}/forum/posting.php?mode=editpost&p={1}", + Settings.Current.HostRuTrackerOrg, str1); + if (_webClient == null) + DownloadWebPage(_url); + var headers = new NameValueCollection(); + _webClient.multipart = true; + _webClient.Upload(_url, headers, _params); + _webClient.multipart = false; + break; + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Warn(ex.StackTrace); + _logger.Debug(ex); + //if (index2 == 20) + throw new Exception("Не удалось отправить отчет за 1 попытку. Ошибка " + ex.Message); +// Thread.Sleep(index2 * 1000); + } + + Thread.Sleep(1000); + } + + public void ReadKeeperInfo() + { + var str = DownloadWebPage(string.Format("https://{1}/forum/profile.php?mode=viewprofile&u={0}", + _userName, Settings.Current.HostRuTrackerOrg)).Split('\r', '\n').Where(x => + { + if (x.Contains("bt:")) + return x.Contains("api:"); + return false; + }).FirstOrDefault(); + if (string.IsNullOrWhiteSpace(str)) + return; + _apiId = str.Split(new string[2] + { + "", + "" + }, StringSplitOptions.RemoveEmptyEntries)[3]; + _keeperId = int.Parse(str.Split(new string[2] + { + "", + "" + }, StringSplitOptions.RemoveEmptyEntries)[5]); + + _logger.Info("Результат авторизации: KeeperID: {0}; KeeperApiKey: {1}", _keeperId, _apiId); + } + } +} diff --git a/TLO/Clients/TLOWebClient.cs b/TLO/Clients/TLOWebClient.cs new file mode 100644 index 0000000..c7d9166 --- /dev/null +++ b/TLO/Clients/TLOWebClient.cs @@ -0,0 +1,373 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using NLog; + +namespace TLO.Clients +{ + internal class TloWebClient : WebClient + { + private static Logger _logger; + private readonly string _accept = string.Empty; + private readonly string _userAgent; + private bool _isJson; + private readonly bool _enableProxy; + + public TloWebClient(bool enableProxy = false) + : this(null, null, null, enableProxy: enableProxy) + { + } + + public TloWebClient(Encoding encoding) + : this(encoding, null, null, enableProxy: true) + { + } + + public TloWebClient(Encoding encoding, string userAgent, string accept, bool isJson = false, + bool enableProxy = false) + { + if (_logger == null) + _logger = LogManager.GetCurrentClassLogger(); + Encoding encoding1; + if (encoding != null) + encoding1 = encoding; + else + encoding = encoding1 = Encoding.UTF8; + Encoding = encoding1; + _userAgent = string.IsNullOrWhiteSpace(userAgent) + ? "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0" + : userAgent; + _accept = string.IsNullOrWhiteSpace(accept) + ? "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + : accept; + CookieContainer = new CookieContainer(); + _isJson = isJson; + _enableProxy = enableProxy; + } + + public TloWebClient(string userAgent) + { + _userAgent = userAgent; + } + + public bool multipart = false; + + public CookieContainer CookieContainer { get; } + + protected override WebRequest GetWebRequest(Uri address) + { + var webRequest = (HttpWebRequest) base.GetWebRequest(address); + if (webRequest == null) + { + throw new Exception("Empty WebRequest"); + } + + if (!_enableProxy) + { + webRequest.Proxy = new WebProxy(); + } + + webRequest.Accept = _isJson ? "application/json" : _accept; + webRequest.UserAgent = _userAgent; + webRequest.Headers.Add("Accept-Encoding", "gzip, deflate"); + webRequest.Headers.Add("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"); + if (_isJson) + { + webRequest.Headers.Add("X-Request", "JSON"); + webRequest.Headers.Add("X-Requested-With", "XMLHttpRequest"); + } + + if (multipart) + { + // webRequest.ContentType = "multipart/form-data"; + } + else if(webRequest.Method == "POST" || webRequest.Method == "post") + { + webRequest.ContentType = "application/x-www-form-urlencoded"; + } + webRequest.KeepAlive = true; + webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + webRequest.Headers.Add("Pragma", "no-cache"); + webRequest.Timeout = 60000; + + webRequest.CookieContainer = CookieContainer; + if (Settings.Current.DisableServerCertVerify.GetValueOrDefault(false)) + webRequest.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; + + logRequest(webRequest); + + return webRequest; + } + + protected override WebResponse GetWebResponse(WebRequest request) + { + WebResponse response; + try + { + response = base.GetWebResponse(request); + } + catch (WebException e) + { + if (e.Response != null) logResponse((HttpWebResponse) e.Response); + + throw; + } + catch (Exception e) + { + if (!(e.InnerException is WebException)) + { + throw; + } + + logResponse((HttpWebResponse) request.GetResponse()); + + throw; + } + + if (response != null) + { + logResponse((HttpWebResponse) response); + } + + return response; + } + + + private static void logRequest(WebRequest webRequest) + { + var request = webRequest as HttpWebRequest; + + var body = ""; + try + { + if (request != null) body = new StreamReader(request.GetRequestStream()).ReadToEnd(); + } + catch (Exception e) + { + body = e.Message; + } + + if (request != null) + _logger.Trace( + $"\r\n\r\nSENDING HTTP REQUEST {request.RequestUri}\r\n{request.Method} {request.RequestUri.PathAndQuery} HTTP/{request.ProtocolVersion}\r\n" + + request.Headers + "\r\n\r\n" + body + ); + } + + private static void logResponse(HttpWebResponse response) + { + var responseStream = response.GetResponseStream(); + + if (responseStream != null) + { + Stream streamReplace = new MemoryStream(); + responseStream.CopyTo(streamReplace); + streamReplace.Seek(0, SeekOrigin.Begin); + + var length = streamReplace.Length; + var buffer = new byte[length]; + var read = 0; + do + { + var readed = streamReplace.Read(buffer, 0, (int) length); + read += readed; + } while (read < length); + + _logger.Trace($"Charset {response.CharacterSet}"); + + var text = response.CharacterSet != null && response.CharacterSet.ToLower().Contains("1251") + ? Encoding.GetEncoding(1251).GetString(buffer) + : Encoding.GetEncoding("UTF-8").GetString(buffer); + + // var text = ""; + streamReplace.Seek(0, SeekOrigin.Begin); + + var fieldInfo = response + .GetType() + .GetField( + "m_ConnectStream", + BindingFlags.Instance | BindingFlags.NonPublic + ); + if (fieldInfo != null) fieldInfo.SetValue(response, streamReplace); + var httpWebResponse = response; + response.Headers["Set-Cookie"] = "--HIDDEN FOR SECURITY REASONS--"; + _logger.Trace( + $"\r\n\r\nRECEIVED HTTP RESPONSE\r\nHTTP/{httpWebResponse.ProtocolVersion} {(int) httpWebResponse.StatusCode} {httpWebResponse.StatusDescription}\r\n" + + response.Headers + + "\r\n\r\n" + + text); + } + } + + public string GetString(string url) + { + _isJson = false; + return DownloadString(url); + } + + public string GetJson(string url) + { + _isJson = true; + return DownloadString(url); + } + + public class MimePart + { + NameValueCollection _headers = new NameValueCollection(); + byte[] _header; + + public NameValueCollection Headers + { + get { return _headers; } + } + + public byte[] Header + { + get { return _header; } + } + + public long GenerateHeaderFooterData(string boundary) + { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.Append("--"); + stringBuilder.Append(boundary); + stringBuilder.AppendLine(); + foreach (string key in _headers.AllKeys) + { + stringBuilder.Append(key); + stringBuilder.Append(": "); + stringBuilder.AppendLine(_headers[key]); + } + stringBuilder.AppendLine(); + + _header = Encoding.UTF8.GetBytes(stringBuilder.ToString()); + + return _header.Length + Data.Length + 2; + } + + public Stream Data { get; set; } + } + + public class UploadResponse + { + public UploadResponse(HttpStatusCode httpStatusCode, string responseBody) + { + HttpStatusCode = httpStatusCode; + ResponseBody = responseBody; + } + + public HttpStatusCode HttpStatusCode { get; set; } + + public string ResponseBody { get; set; } + } + + public UploadResponse Upload(string url, NameValueCollection requestHeaders, NameValueCollection requestParameters) + { + using (WebClient client = this) + { + + List mimeParts = new List(); + + try + { + foreach (string key in requestHeaders.AllKeys) + { + client.Headers.Add(key, requestHeaders[key]); + } + + foreach (string key in requestParameters.AllKeys) + { + MimePart part = new MimePart(); + + part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\""; + part.Data = new MemoryStream(Encoding.GetBytes(requestParameters[key])); + + mimeParts.Add(part); + } + + // foreach (FileInfo file in files) + // { + // MimePart part = new MimePart(); + // string name = file.Extension.Substring(1); + // string fileName = file.Name; + // + // part.Headers["Content-Disposition"] = "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\""; + // part.Headers["Content-Type"] = "application/octet-stream"; + // + // part.Data = new MemoryStream(File.ReadAllBytes(file.FullName)); + // + // mimeParts.Add(part); + // } + + string boundary = "----------" + DateTime.Now.Ticks.ToString("x"); + client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary); + + long contentLength = 0; + + byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n"); + + foreach (MimePart mimePart in mimeParts) + { + contentLength += mimePart.GenerateHeaderFooterData(boundary); + } + + byte[] buffer = new byte[8192]; + byte[] afterFile = Encoding.UTF8.GetBytes("\r\n"); + int read; + + using (MemoryStream memoryStream = new MemoryStream()) + { + foreach (MimePart mimePart in mimeParts) + { + memoryStream.Write(mimePart.Header, 0, mimePart.Header.Length); + + while ((read = mimePart.Data.Read(buffer, 0, buffer.Length)) > 0) + memoryStream.Write(buffer, 0, read); + + mimePart.Data.Dispose(); + + memoryStream.Write(afterFile, 0, afterFile.Length); + } + + memoryStream.Write(_footer, 0, _footer.Length); + var array = memoryStream.ToArray(); + System.Console.WriteLine(Encoding.GetString(array)); + System.Console.Out.Flush(); + byte[] responseBytes = client.UploadData(url, array); + string responseString = Encoding.UTF8.GetString(responseBytes); + return new UploadResponse(HttpStatusCode.OK, responseString); + } + } + catch (Exception ex) + { + foreach (MimePart part in mimeParts) + if (part.Data != null) + part.Data.Dispose(); + + if (ex.GetType().Name == "WebException") + { + WebException webException = (WebException)ex; + HttpWebResponse response = (HttpWebResponse)webException.Response; + string responseString; + + using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) + { + responseString = reader.ReadToEnd(); + } + + return new UploadResponse(response.StatusCode, responseString); + } + else + { + throw; + } + } + } + } + } +} \ No newline at end of file diff --git a/TLO/Clients/TixatiClient.cs b/TLO/Clients/TixatiClient.cs new file mode 100644 index 0000000..bc99084 --- /dev/null +++ b/TLO/Clients/TixatiClient.cs @@ -0,0 +1,356 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using AngleSharp.Html.Parser; +using AngleSharp.Text; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class TixatiClient : ITorrentClient + { + public const string ClientId = "Tixati"; + public string Id => ClientId; + private readonly TloWebClient _client; + private readonly Uri _baseUri; + private readonly UriTemplate _uriTemplate; + private readonly UriTemplate _uriTemplate1; + private readonly UriTemplate _uriTemplateFree; + private readonly string _host; + private readonly int _port; + private readonly string _username; + private readonly string _password; + private readonly Logger Logger = LogManager.GetLogger("Tixati"); + + public TixatiClient(string host, int port, string username, string password) + { + _baseUri = new Uri($"http://{host}:{port}/"); + _uriTemplate = new UriTemplate("{section}/{methodName}"); + _uriTemplate1 = new UriTemplate("{section}"); + _uriTemplateFree = new UriTemplate("{url}"); + _client = new TloWebClient(Encoding.UTF8, "TLO", "text/*,application/*", true); + _host = host; + _port = port; + _username = username; + _password = password; + _client.Headers.Add("Referer", _baseUri.ToString()); + _client.UseDefaultCredentials = true; + + // if (this.Ping()) + // { + // authorize(); + // } + } + + private void authorize() + { + // try + // { + // var auth = _uriTemplate.BindByName(_baseUri, new Dictionary + // { + // {"section", "auth"}, {"methodName", "login"} + // }); + // + // var builder = new UriBuilder(auth); + // builder.Query = $"username={_username}&password={_password}"; + // var result = _client.DownloadString(builder.Uri); + // Logger.Log(LogLevel.Debug, "Auth: " + result); + // } + // catch (WebException e) + // { + // Logger.Error(e); + // Logger.Error(e.StackTrace); + // } + } + + public List GetAllTorrentHash() + { + var uri = _uriTemplate1.BindByName(_baseUri, new Dictionary + { + {"section", "transfers"} + }); + string result; + try + { + result = _client.DownloadString(uri); + } + catch (WebException e) + { + Logger.Error(e); + Logger.Error(e.StackTrace); + + throw e; + } + + var parser = new HtmlParser(); + var document = parser.ParseDocument(result); + var trs = document.QuerySelector("table.xferstable").QuerySelectorAll("tr"); + var first = true; + + var torrents = new List(); + foreach (var tr in trs) + { + if (first) + { + first = false; + continue; + } + var a = tr.QuerySelector("td > a"); + var link = a.Attributes.GetNamedItem("href").Value; + var downloaded = tr.QuerySelectorAll("td")[3].TextContent.Trim().ToInteger(0); + var stopped = tr.QuerySelectorAll("td")[4].TextContent.Trim() == "Offline"; + + var detailUri = _uriTemplateFree.BindByName(_baseUri, new Dictionary + { + {"url", link.Trim('/')} + }); + var eventlogUri = _uriTemplateFree.BindByName(_baseUri, new Dictionary + { + {"url", link.Trim('/').Replace("details", "eventlog")} + }); + + string details; + string eventlog; + try + { + details = _client.DownloadString(detailUri); + eventlog = _client.DownloadString(eventlogUri); + } + catch (WebException e) + { + Logger.Error(e); + Logger.Error(e.StackTrace); + + throw e; + } + + var detailsDocument = parser.ParseDocument(details); + var title = detailsDocument.QuerySelector("div.titlehdr").TextContent.Trim(); + var seeders = detailsDocument.QuerySelector("table.xferdetailstoprightstats").QuerySelectorAll("tr")[1].ChildNodes[1].TextContent.ToInteger(0); + var leechers = detailsDocument.QuerySelector("table.xferdetailstoprightstats").QuerySelectorAll("tr")[2].ChildNodes[1].TextContent.ToInteger(0); + + var info = new TopicInfo(); + + info.Hash = Regex.Match(eventlog, "info-hash set to ([A-Z0-9]+)").Groups[1].Value; + info.Name2 = title; + info.TorrentName = title; + info.Size = 0; + info.Seeders = seeders; + info.Leechers = leechers; + info.Label = ""; + info.IsRun = !stopped; + info.IsKeep = downloaded == 100; + info.IsPause = stopped; + info.IsDownload = !stopped && downloaded != 100; + Logger.Error(info.ToString()); + torrents.Add(info); + } + + return torrents; + } + + public IEnumerable GetFiles(TopicInfo topic) + { + return new string[0]; // TODO + throw new NotImplementedException(); + } + + public void DistributionStop(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public void DistributionPause(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public void DistributionStart(IEnumerable data) + { + return; // TODO + throw new NotImplementedException(); + } + + public bool Ping() + { + try + { + var uri = _uriTemplate1.BindByName(_baseUri, new Dictionary + { + {"section", "home"} + }); + var data = _client.DownloadString(uri); + + return true; + } + catch(Exception e) + { + Console.WriteLine(e.Message); + return false; + } + } + + public bool SetDefaultFolder(string dir) + { + return true; // TODO + throw new NotImplementedException(); + } + + public bool SetDefaultLabel(string label) + { + return true; // TODO + throw new NotImplementedException(); + } + + public string GetDefaultFolder() + { + return ""; // TODO + throw new NotImplementedException(); + } + + public void SendTorrentFile(string path, string file) + { + return; // TODO + throw new NotImplementedException(); + } + + public void SendTorrentFile(string path, string filename, byte[] fdata) + { + var uri = _uriTemplateFree.BindByName(_baseUri, new Dictionary + { + {"url", "transfers/action"} + }); + + var str = "----WebKitFormBoundary1vZaMilolI9TchBt"; + using (var memoryStream = new MemoryStream()) + { + var bytes0 = Encoding.UTF8.GetBytes( + $"--{str}\r\nContent-Disposition: form-data; name=\"savepath\"\r\n\r\n{path}\r\n" + + $"--{str}\r\nContent-Disposition: form-data; name=\"addmetafile\"\r\n\r\nAdd\r\n" + + $"--{str}\r\nContent-Disposition: form-data; name=\"noautostart\"\r\n\r\n1\r\n"); + var bytes1 = Encoding.UTF8.GetBytes( + $"--{str}\r\nContent-Disposition: form-data; name=\"metafile\"; filename=\"{filename}\"\r\nContent-Type: application/x-bittorrent\r\n\r\n"); + memoryStream.Write(bytes0, 0, bytes0.Length); + memoryStream.Write(bytes1, 0, bytes1.Length); + memoryStream.Write(fdata, 0, fdata.Length); + var bytes2 = Encoding.UTF8.GetBytes($"\r\n--{str}--\r\n"); + memoryStream.Write(bytes2, 0, bytes2.Length); + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Host = this._host; + httpWebRequest.Method = "POST"; + httpWebRequest.KeepAlive = true; + httpWebRequest.ContentType = "multipart/form-data; boundary=" + str; + httpWebRequest.CookieContainer = _client.CookieContainer; + var array = memoryStream.ToArray(); + httpWebRequest.ContentLength = array.Length; + using (var requestStream = httpWebRequest.GetRequestStream()) + { + requestStream.Write(array, 0, array.Length); + requestStream.Flush(); + requestStream.Close(); + } + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + Logger.Error(reader.ReadToEnd()); + reader.Close(); + } + } + + public string[] GetTrackers(string hash) + { + return new string[0]; // TODO + throw new NotImplementedException(); + } + + public bool SetTrackers(string hash, string[] trackers) + { + return true; // TODO + throw new NotImplementedException(); + } + + public bool SetLabel(string hash, string label) + { + return true; + try + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "addTags"} + }); + var data = $"hashes={hash.ToLower()}&tags={WebUtility.UrlEncode(label.Replace(",", "‚"))}"; + var bytes = Encoding.UTF8.GetBytes(data); + + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Method = "POST"; + httpWebRequest.ContentType = "application/x-www-form-urlencoded"; + httpWebRequest.CookieContainer = _client.CookieContainer; + httpWebRequest.ContentLength = bytes.Length; + var stream = httpWebRequest.GetRequestStream(); + stream.Write(bytes, 0, bytes.Length); + stream.Flush(); + stream.Close(); + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + reader.ReadToEnd(); + reader.Close(); + return true; + } + catch (WebException e) + { + Logger.Error(e.Message); + Logger.Error(e.StackTrace); + return false; + } + } + + public bool SetLabel(IEnumerable hash, string label) + { + return true; + try + { + var uri = _uriTemplate.BindByName(_baseUri, new Dictionary + { + {"section", "torrents"}, {"methodName", "addTags"} + }); + var data = + $"hashes={string.Join("|", hash.ToList().ConvertAll((input => input.ToLower())))}&tags={WebUtility.UrlEncode(label.Replace(",", "‚"))}"; + var bytes = Encoding.UTF8.GetBytes(data); + + var httpWebRequest = (HttpWebRequest) WebRequest.Create(uri); + httpWebRequest.Method = "POST"; + httpWebRequest.ContentType = "application/x-www-form-urlencoded"; + httpWebRequest.CookieContainer = _client.CookieContainer; + httpWebRequest.ContentLength = bytes.Length; + var stream = httpWebRequest.GetRequestStream(); + stream.Write(bytes, 0, bytes.Length); + stream.Flush(); + stream.Close(); + + var response = httpWebRequest.GetResponse(); + var responseStream = response.GetResponseStream(); + var reader = new StreamReader(responseStream); + reader.ReadToEnd(); + reader.Close(); + + return true; + } + catch (WebException e) + { + Logger.Error(e.Message); + Logger.Error(e.StackTrace); + return false; + } + } + } +} \ No newline at end of file diff --git a/TLO/Clients/TransmissionClient.cs b/TLO/Clients/TransmissionClient.cs new file mode 100644 index 0000000..3c9c84f --- /dev/null +++ b/TLO/Clients/TransmissionClient.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using Newtonsoft.Json; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class TransmissionClient : ITorrentClient + { + public const string ClientId = "Transmission"; + public string Id => ClientId; + private static Logger _logger; + private readonly string _url; + private readonly TloWebClient _webClient; + + public TransmissionClient(string serverName, int port, string userName, string userPass) + { + if (_logger == null) + _logger = LogManager.GetLogger("TransmissionClient"); + _webClient = new TloWebClient(Encoding.UTF8, + "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0", + "application/json, text/javascript, */*; q=0.01", true); + _webClient.Encoding = Encoding.UTF8; + var svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + userPass)); + _webClient.Headers.Add("Authorization", "Basic " + svcCredentials); + _url = string.Format("http://{0}:{1}/transmission/rpc", serverName, port); + // try + // { + // Ping(); + // } + // catch + // { + // _logger.Debug(string.Format("Имя сервера: {0}; Порт сервера: {1}", serverName, port)); + // throw; + // } + } + + public List GetAllTorrentHash() + { + try + { + var querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString( + _webClient.UploadData(_url, "POST", + Encoding.UTF8.GetBytes( + "{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"totalSize\", \"percentDone\", \"error\", \"status\"]}}")))); + if (querty == null || querty.Arguments == null || querty.Arguments.Torrents == null || + querty.Arguments.Torrents.Length == 0) + return new List(); + return querty.Arguments.Torrents.Select(t => new TopicInfo + { + Hash = t.HashString.ToUpper(), + IsKeep = t.PercentDone == decimal.One && t.Error == 0, + IsDownload = true, + IsRun = !(t.PercentDone == decimal.One) || t.Error != 0 ? new bool?() : t.Status == 6 + }).ToList(); + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Debug(ex.StackTrace); + throw ex; + } + } + + public IEnumerable GetFiles(TopicInfo topic) + { + yield break; + } + + public void DistributionStop(IEnumerable data) + { + var querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(_webClient.UploadData(_url, + "POST", + Encoding.UTF8.GetBytes( + "{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); + if (querty == null || querty.Arguments == null || querty.Arguments.Torrents == null || + querty.Arguments.Torrents.Length == 0) + return; + var array = querty.Arguments.Torrents.Join(data, t => t.HashString.ToUpper(), d => d, (t, d) => t.Id) + .ToArray(); + if (array.Length == 0) + return; + _webClient.UploadData(_url, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new + { + method = "torrent-stop", + arguments = new {ids = array} + }))); + } + + public void DistributionPause(IEnumerable data) + { + var querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(_webClient.UploadData(_url, + "POST", + Encoding.UTF8.GetBytes( + "{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); + if (querty == null || querty.Arguments == null || querty.Arguments.Torrents == null || + querty.Arguments.Torrents.Length == 0) + return; + var array = querty.Arguments.Torrents.Join(data, t => t.HashString.ToUpper(), d => d, (t, d) => t.Id) + .ToArray(); + if (array.Length == 0) + return; + _webClient.UploadData(_url, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new + { + method = "torrent-stop", + arguments = new {ids = array} + }))); + } + + public void DistributionStart(IEnumerable data) + { + var querty = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(_webClient.UploadData(_url, + "POST", + Encoding.UTF8.GetBytes( + "{\"method\":\"torrent-get\",\"arguments\":{\"fields\":[\"hashString\", \"id\"]}}")))); + if (querty == null || querty.Arguments == null || querty.Arguments.Torrents == null || + querty.Arguments.Torrents.Length == 0) + return; + var array = querty.Arguments.Torrents.Join(data, t => t.HashString.ToUpper(), d => d, (t, d) => t.Id) + .ToArray(); + if (array.Length == 0) + return; + _webClient.UploadData(_url, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new + { + method = "torrent-start", + arguments = new {ids = array} + }))); + } + + public bool Ping() + { + while (true) + try + { + _webClient.UploadData(_url, "POST", Encoding.UTF8.GetBytes("{\"method\":\"session-get\"}")); + return true; + } + catch (WebException ex) + { + _webClient.Headers.Add("X-Transmission-Session-Id", + ex.Response.Headers["X-Transmission-Session-Id"]); + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Debug(ex.StackTrace); + throw ex; + } + } + + public bool SetDefaultFolder(string dir) + { + return true; + } + + public bool SetDefaultLabel(string label) + { + return true; + } + + public string GetDefaultFolder() + { + return string.Empty; + } + + public void SendTorrentFile(string path, string file) + { + using (var memoryStream = new MemoryStream()) + { + using (var fileStream = File.OpenRead(file)) + { + fileStream.CopyTo(memoryStream); + SendTorrentFile(path, Path.GetFileName(file), memoryStream.ToArray()); + } + } + } + + public void SendTorrentFile(string path, string filename, byte[] fdata) + { + var base64String = Convert.ToBase64String(fdata); + _webClient.UploadData(_url, "POST", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new + { + method = "torrent-add", + arguments = new + { + paused = false, + downloadDir = path, + metainfo = base64String + } + }).Replace("downloadDir", "download-dir"))); + } + + public string[] GetTrackers(string hash) + { + return null; + } + + public bool SetTrackers(string hash, string[] trackers) + { + return true; + } + + public bool SetLabel(string hash, string label) + { + return true; + } + + public bool SetLabel(IEnumerable hash, string label) + { + return true; + } + + private class Querty + { + public Argument Arguments { get; set; } + } + + private class Argument + { + public Torrent[] Torrents { get; set; } + } + + private class Torrent + { + public int Id { get; set; } + + public string HashString { get; set; } + + public long TotalSize { get; set; } + + public decimal PercentDone { get; set; } + + public int Error { get; set; } + + public int Status { get; set; } + } + } +} \ No newline at end of file diff --git a/TLO/Clients/UTorrentClient.cs b/TLO/Clients/UTorrentClient.cs new file mode 100644 index 0000000..9555ef4 --- /dev/null +++ b/TLO/Clients/UTorrentClient.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading; +using System.Web; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using TLO.Info; + +namespace TLO.Clients +{ + internal class UTorrentClient : ITorrentClient + { + public const string ClientId = "uTorrent"; + public string Id => ClientId; + private static Logger _logger; + private readonly string _serverName; + private readonly int _serverPort; + private readonly TloWebClient _webClient; + private string _token; + + public UTorrentClient(string serverName, int port, string userName, string userPass) + { + if (_logger == null) + _logger = LogManager.GetLogger("uTorrentClient"); + _webClient = new TloWebClient(); + _webClient.Encoding = Encoding.UTF8; + var svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + userPass)); + _webClient.Headers.Add("Authorization", "Basic " + svcCredentials); + _serverName = serverName; + _serverPort = port; + // try + // { + // Ping(); + // } + // catch + // { + // _logger.Debug(string.Format("Имя сервера: {0}; Порт сервера: {1}", _serverName, _serverPort)); + // throw; + // } + } + + public bool Ping() + { + var array = _webClient.GetString(string.Format("http://{0}:{1}/gui/", _serverName, _serverPort)).Split( + new string[1] + { + "div" + }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.Contains("token")).ToArray(); + if (array.Length != 0) + _token = array[0].Split(new char[2] + { + '>', + '<' + }, StringSplitOptions.RemoveEmptyEntries)[1]; + else + _token = null; + return true; + } + + public List GetAllTorrentHash() + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"list", "1"}); + var objArray = + JsonConvert.DeserializeObject(_webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", + _serverName, _serverPort, string.Join("&", source.Select(x => string.Join("=", x))))))[ + "torrents"] + .ToObject(); + if (objArray == null) + return new List(); + return objArray.Select(x => new + { + Hash = (x[0] as string).ToUpper(), + Name = x[2] as string, + Size = x[3].GetType() == typeof(int) + ? (long) (int) x[3] + : x[3].GetType() == typeof(long) + ? (long) x[3] + : 0L, + Status = IntToArrayBool((long) x[1]), + PercentComplite = (decimal) (long) x[4] * new decimal(1, 0, 0, false, 1), + Label = x[11] as string + }).Select(x => new TopicInfo + { + Hash = x.Hash, + TorrentName = x.Name, + Size = x.Size, + IsKeep = x.Status != null && x.PercentComplite == new decimal(100) && x.Status[3] && !x.Status[4] && + x.Status[7], + IsDownload = true, + IsPause = x.Status[5], + IsRun = !(x.PercentComplite == new decimal(100)) || !x.Status[3] || x.Status[4] || !x.Status[7] + ? new bool?() + : x.Status[0], + Label = x.Label + }).ToList(); + } + + public IEnumerable GetFiles(TopicInfo topic) + { + if (topic != null && !string.IsNullOrEmpty(topic.Hash)) + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "getfiles"}); + source.Add(new string[2] {"hash", topic.Hash}); + var jtoken1 = JsonConvert.DeserializeObject(_webClient.GetJson( + string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))))["files"]; + if (jtoken1 != null) + foreach (var jtoken2 in (IEnumerable) jtoken1.ToObject()[1].ToObject()) + yield return jtoken2.ToObject()[0].ToString(); + } + } + + public void DistributionStop(IEnumerable data) + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "stop"}); + source.AddRange(data.Select(x => new string[2] + { + "hash", + x + })); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + } + + public void DistributionPause(IEnumerable data) + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "pause"}); + source.AddRange(data.Select(x => new string[2] + { + "hash", + x + })); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + } + + public void DistributionStart(IEnumerable data) + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "start"}); + source.AddRange(data.Select(x => new string[2] + { + "hash", + x + })); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + } + + public bool SetDefaultFolder(string dir) + { + try + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "setsetting"}); + source.Add(new string[2] + { + "s", + "dir_active_download" + }); + source.Add(new string[2] + { + "v", + HttpUtility.UrlEncode(dir) + }); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + Thread.Sleep(100); + return GetDefaultFolder() == dir; + } + catch + { + return false; + } + } + + public string GetDefaultFolder() + { + try + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "getsettings"}); + var objArray1 = + JsonConvert.DeserializeObject(_webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", + _serverName, _serverPort, string.Join("&", source.Select(x => string.Join("=", x)))))) + ["settings"].ToObject(); + if (objArray1 == null) + return string.Empty; + var objArray2 = objArray1.Where(x => x[0] as string == "dir_active_download").FirstOrDefault(); + if (objArray2 == null) + return string.Empty; + return objArray2[2] as string; + } + catch + { + return null; + } + } + + public bool SetDefaultLabel(string label) + { + try + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "setsetting"}); + source.Add(new string[2] {"s", "dir_add_label"}); + source.Add(new string[2] + { + "v", + HttpUtility.UrlEncode(label) + }); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + Thread.Sleep(200); + return GetDefaultLabel() == label; + } + catch + { + return false; + } + } + + public void SendTorrentFile(string path, string file) + { + using (var memoryStream = new MemoryStream()) + { + using (var fileStream = File.OpenRead(file)) + { + fileStream.CopyTo(memoryStream); + SendTorrentFile(path, Path.GetFileName(file), memoryStream.ToArray()); + } + } + } + + public void SendTorrentFile(string path, string filename, byte[] fdata) + { + var str = "----WebKitFormBoundary1vZaMilolI9TchBt"; + using (var memoryStream = new MemoryStream()) + { + var bytes1 = Encoding.ASCII.GetBytes(string.Format( + "--{0}\r\nContent-Disposition: form-data; name=\"torrent_file\"; filename=\"{1}\"\r\nContent-Type: application/x-bittorrent\r\n\r\n", + str, filename)); + memoryStream.Write(bytes1, 0, bytes1.Length); + memoryStream.Write(fdata, 0, fdata.Length); + var bytes2 = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}--\r\n", str)); + memoryStream.Write(bytes2, 0, bytes2.Length); + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "add-file"}); + var httpWebRequest = (HttpWebRequest) WebRequest.Create( + string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + httpWebRequest.Method = "POST"; + httpWebRequest.KeepAlive = true; + httpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; + httpWebRequest.ContentType = "multipart/form-data; boundary=" + str; + httpWebRequest.Headers.Add("Authorization", _webClient.Headers.Get("Authorization")); + httpWebRequest.Headers.Add("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"); + var array = memoryStream.ToArray(); + httpWebRequest.ContentLength = array.Length; + using (var requestStream = httpWebRequest.GetRequestStream()) + { + requestStream.Write(array, 0, array.Length); + } + } + } + + public string[] GetTrackers(string hash) + { + return null; + } + + public bool SetTrackers(string hash, string[] trackers) + { + try + { + var str = string.Join("\r\n\r\n", trackers) + "\r\n"; + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"setprops", "setprops"}); + source.Add(new string[2] {"hash", hash}); + source.Add(new string[2] {"s", "trackers"}); + source.Add(new string[2] + { + "v", + HttpUtility.UrlEncode(str) + }); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + Thread.Sleep(100); + var trackers1 = GetTrackers(hash); + if (trackers1 == null) + return false; + return string.Join("\r\n\r\n", trackers1) + "\r\n" == str; + } + catch + { + return false; + } + } + + public bool SetLabel(string hash, string label) + { + Thread.Sleep(100); + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "setprops"}); + source.Add(new string[2] {"hash", hash}); + source.Add(new string[2] {"s", "label"}); + source.Add(new string[2] {"v", label}); + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + Thread.Sleep(100); + return true; + } + + public bool SetLabel(IEnumerable hashs, string label) + { + if (hashs == null || hashs.Count() == 0) + return true; + var source = new List(); + foreach (var str in hashs) + { + if (source.Count() == 0) + { + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "setprops"}); + } + + source.Add(new string[2] {"s", "label"}); + source.Add(new string[2] {"hash", str}); + source.Add(new string[2] {"v", label}); + if (source.Count() > 150) + { + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + source.Clear(); + } + + Thread.Sleep(100); + } + + if (source.Count() != 0) + _webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", _serverName, _serverPort, + string.Join("&", source.Select(x => string.Join("=", x))))); + return true; + } + + private bool[] IntToArrayBool(long value) + { + var bitArray = new BitArray(new int[1] + { + (int) value + }); + var flagArray = new bool[bitArray.Count]; + bitArray.CopyTo(flagArray, 0); + return flagArray; + } + + public string GetDefaultLabel() + { + try + { + var source = new List(); + if (!string.IsNullOrWhiteSpace(_token)) + source.Add(new string[2] {"token", _token}); + source.Add(new string[2] {"action", "getsettings"}); + var objArray1 = + JsonConvert.DeserializeObject(_webClient.GetJson(string.Format("http://{0}:{1}/gui/?{2}", + _serverName, _serverPort, string.Join("&", source.Select(x => string.Join("=", x)))))) + ["settings"].ToObject(); + if (objArray1 == null) + return string.Empty; + var objArray2 = objArray1.Where(x => x[0] as string == "dir_add_label").FirstOrDefault(); + if (objArray2 == null) + return string.Empty; + return objArray2[2] as string; + } + catch + { + return null; + } + } + + private class Tt + { + public int Build { get; set; } + + public List Files { get; set; } + } + } +} \ No newline at end of file diff --git a/TLO/Forms/FolderNameDialog.Designer.cs b/TLO/Forms/FolderNameDialog.Designer.cs new file mode 100644 index 0000000..304ca7f --- /dev/null +++ b/TLO/Forms/FolderNameDialog.Designer.cs @@ -0,0 +1,95 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace TLO.Forms +{ + partial class FolderNameDialog + { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + + private void InitializeComponent() + { + btCancel = new Button(); + btOk = new Button(); + btAbort = new Button(); + txtFolderName = new TextBox(); + SuspendLayout(); + btCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + btCancel.Location = new Point(426, 38); + btCancel.Name = "btCancel"; + btCancel.Size = new Size(75, 23); + btCancel.TabIndex = 0; + btCancel.Text = "Пропустить"; + btCancel.UseVisualStyleBackColor = true; + btCancel.Click += ClickButton; + btOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + btOk.Location = new Point(345, 38); + btOk.Name = "btOk"; + btOk.Size = new Size(75, 23); + btOk.TabIndex = 1; + btOk.Text = "Применить"; + btOk.UseVisualStyleBackColor = true; + btOk.Click += ClickButton; + btAbort.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + btAbort.Location = new Point(12, 38); + btAbort.Name = "btAbort"; + btAbort.Size = new Size(75, 23); + btAbort.TabIndex = 2; + btAbort.Text = "Прервать"; + btAbort.UseVisualStyleBackColor = true; + btAbort.Click += ClickButton; + txtFolderName.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + txtFolderName.Location = new Point(12, 12); + txtFolderName.Name = "txtFolderName"; + txtFolderName.Size = new Size(489, 20); + txtFolderName.TabIndex = 3; + AutoScaleDimensions = new SizeF(6f, 13f); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(513, 73); + ControlBox = false; + Controls.Add(txtFolderName); + Controls.Add(btAbort); + Controls.Add(btOk); + Controls.Add(btCancel); + FormBorderStyle = FormBorderStyle.FixedToolWindow; + MaximizeBox = false; + MinimizeBox = false; + Name = "FolderNameDialog"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Запрос наименования каталога"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button btCancel; + private Button btOk; + private Button btAbort; + private TextBox txtFolderName; + } +} \ No newline at end of file diff --git a/TLO/Forms/FolderNameDialog.cs b/TLO/Forms/FolderNameDialog.cs new file mode 100644 index 0000000..bf0c27b --- /dev/null +++ b/TLO/Forms/FolderNameDialog.cs @@ -0,0 +1,50 @@ +using System; +using System.IO; +using System.Linq; +using System.Windows.Forms; + +namespace TLO.Forms +{ + internal partial class FolderNameDialog : Form + { + public FolderNameDialog() + { + InitializeComponent(); + } + + public string SelectedPath + { + get => txtFolderName.Text; + set => txtFolderName.Text = string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim(); + } + + private void ClickButton(object sender, EventArgs e) + { + if (sender == btAbort) + { + DialogResult = DialogResult.Abort; + Close(); + } + else if (sender == btCancel) + { + DialogResult = DialogResult.Cancel; + Close(); + } + else + { + if (sender != btOk) + return; + foreach (var invalidFileNameChar in Path.GetInvalidFileNameChars()) + if (SelectedPath.Contains(invalidFileNameChar)) + { + var num = (int) MessageBox.Show("Название каталога содержит недопустимый символ: " + + invalidFileNameChar); + return; + } + + DialogResult = DialogResult.OK; + Close(); + } + } + } +} \ No newline at end of file diff --git a/Forms/SettingsForm.resx b/TLO/Forms/FolderNameDialog.resx similarity index 97% rename from Forms/SettingsForm.resx rename to TLO/Forms/FolderNameDialog.resx index 1af7de1..29dcb1b 100644 --- a/Forms/SettingsForm.resx +++ b/TLO/Forms/FolderNameDialog.resx @@ -1,120 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/TLO/Forms/ForumPages.Designer.cs b/TLO/Forms/ForumPages.Designer.cs new file mode 100644 index 0000000..a91dd85 --- /dev/null +++ b/TLO/Forms/ForumPages.Designer.cs @@ -0,0 +1,64 @@ +using System.ComponentModel; +using System.Windows.Forms; + +namespace TLO.Forms { + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + partial class ForumPages { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoScroll = true; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(606, 440); + this.panel1.TabIndex = 0; + // + // ForumPages + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel1); + this.Name = "ForumPages"; + this.Size = new System.Drawing.Size(606, 440); + this.ResumeLayout(false); + + } + + #endregion + + private Panel panel1; + } +} diff --git a/TLO/Forms/ForumPages.cs b/TLO/Forms/ForumPages.cs new file mode 100644 index 0000000..703d44f --- /dev/null +++ b/TLO/Forms/ForumPages.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using TLO.Clients; +using TLO.Info; + +namespace TLO.Forms +{ + internal partial class ForumPages : UserControl + { + public ForumPages() + { + Urls = new List>(); + InitializeComponent(); + } + + private List> Urls { get; } + + public void LoadSettings() + { + panel1.Controls.Clear(); + var reports = ClientLocalDb.Current.GetReports(new int?()); + var categoriesEnable = ClientLocalDb.Current.GetCategoriesEnable(); + categoriesEnable.Add(new Category + { + CategoryID = 0, + Name = " Сводный отчет", + FullName = " Сводный отчет" + }); + var num1 = 0; + var y = 10; + foreach (var category1 in categoriesEnable.OrderBy(x => x.FullName)) + { + var category = category1; + var label = new Label(); + label.AutoSize = true; + label.Location = new Point(3, y); + label.Size = new Size(35, 13); + label.TabIndex = num1; + label.Text = category.FullName; + panel1.Controls.Add(label); + y += 16; + var array = reports.Where(x => x.Key.Item1 == category.CategoryID).OrderBy(x => x.Key.Item2).ToArray(); + KeyValuePair, Tuple>[] keyValuePairArray; + if (array.Length != 0) + keyValuePairArray = array; + else + keyValuePairArray = new KeyValuePair, Tuple>[1] + { + new KeyValuePair, Tuple>( + new Tuple(category.CategoryID, 0), new Tuple("", "")) + }; + foreach (var keyValuePair in keyValuePairArray) + if (category.CategoryID != 0 || keyValuePair.Key.Item2 == 0) + { + var num2 = num1 + 1; + var textBox1 = new TextBox(); + textBox1.Enabled = false; + textBox1.Location = new Point(6, y); + textBox1.Size = new Size(123, 20); + textBox1.TabIndex = num2; + textBox1.Text = "Отчет " + (keyValuePair.Key.Item2 != 0 + ? keyValuePair.Key.Item2 + + (keyValuePair.Value.Item2 == "Резерв" ? " (Резерв)" : "") + : " (Шапка)"); + if (category.CategoryID == 0) + textBox1.Text = "Сводный отчет"; + panel1.Controls.Add(textBox1); + num1 = num2 + 1; + var textBox2 = new TextBox(); + textBox2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox2.Location = new Point(135, y); + textBox2.Size = new Size(panel1.Size.Width - 135, 20); + textBox2.TabIndex = num1; + textBox2.Text = string.IsNullOrWhiteSpace(keyValuePair.Value.Item1) + ? "" + : keyValuePair.Value.Item1; + panel1.Controls.Add(textBox2); + Urls.Add(new Tuple(keyValuePair.Key.Item1, keyValuePair.Key.Item2, + textBox2)); + y += 26; + } + } + } + + public void Save() + { + ClientLocalDb.Current.SaveSettingsReport(Urls + .Select(x => new Tuple(x.Item1, x.Item2, x.Item3.Text)).ToList()); + } + } +} \ No newline at end of file diff --git a/Forms/ForumPages.resx b/TLO/Forms/ForumPages.resx similarity index 100% rename from Forms/ForumPages.resx rename to TLO/Forms/ForumPages.resx diff --git a/TLO/Forms/GetLabelName.Designer.cs b/TLO/Forms/GetLabelName.Designer.cs new file mode 100644 index 0000000..44618df --- /dev/null +++ b/TLO/Forms/GetLabelName.Designer.cs @@ -0,0 +1,90 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace TLO.Forms +{ + partial class GetLabelName + { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + + private void InitializeComponent() + { + _txtLabel = new TextBox(); + label1 = new Label(); + btOk = new Button(); + btCancel = new Button(); + SuspendLayout(); + _txtLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + _txtLabel.Location = new Point(94, 12); + _txtLabel.Name = "_txtLabel"; + _txtLabel.Size = new Size(408, 20); + _txtLabel.TabIndex = 0; + label1.AutoSize = true; + label1.Location = new Point(12, 15); + label1.Name = "label1"; + label1.Size = new Size(76, 13); + label1.TabIndex = 1; + label1.Text = "Новая метка:"; + btOk.Anchor = AnchorStyles.Top | AnchorStyles.Right; + btOk.Location = new Point(427, 38); + btOk.Name = "btOk"; + btOk.Size = new Size(75, 23); + btOk.TabIndex = 2; + btOk.Text = "Применить"; + btOk.UseVisualStyleBackColor = true; + btOk.Click += btClick; + btCancel.Anchor = AnchorStyles.Top | AnchorStyles.Right; + btCancel.Location = new Point(346, 38); + btCancel.Name = "btCancel"; + btCancel.Size = new Size(75, 23); + btCancel.TabIndex = 3; + btCancel.Text = "Отмена"; + btCancel.UseVisualStyleBackColor = true; + btCancel.Click += btClick; + AutoScaleDimensions = new SizeF(6f, 13f); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(514, 72); + Controls.Add(btCancel); + Controls.Add(btOk); + Controls.Add(label1); + Controls.Add(_txtLabel); + FormBorderStyle = FormBorderStyle.None; + Name = "GetLabelName"; + StartPosition = FormStartPosition.CenterScreen; + Text = "GetLabelName"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private TextBox _txtLabel; + private Label label1; + private Button btOk; + private Button btCancel; + } +} \ No newline at end of file diff --git a/TLO/Forms/GetLabelName.cs b/TLO/Forms/GetLabelName.cs new file mode 100644 index 0000000..f1455e8 --- /dev/null +++ b/TLO/Forms/GetLabelName.cs @@ -0,0 +1,34 @@ +using System; +using System.Windows.Forms; + +namespace TLO.Forms +{ + internal partial class GetLabelName : Form + { + public GetLabelName() + { + InitializeComponent(); + } + + internal string Value + { + get => _txtLabel.Text; + set => _txtLabel.Text = value; + } + + private void btClick(object sender, EventArgs e) + { + if (sender == btCancel) + { + DialogResult = DialogResult.Cancel; + Close(); + } + else + { + if (sender != btOk) + return; + DialogResult = DialogResult.OK; + } + } + } +} \ No newline at end of file diff --git a/TLO/Forms/GetLabelName.resx b/TLO/Forms/GetLabelName.resx new file mode 100644 index 0000000..29dcb1b --- /dev/null +++ b/TLO/Forms/GetLabelName.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TLO/Forms/MainForm.Designer.cs b/TLO/Forms/MainForm.Designer.cs new file mode 100644 index 0000000..f1fae5a --- /dev/null +++ b/TLO/Forms/MainForm.Designer.cs @@ -0,0 +1,941 @@ +using System.ComponentModel; +using System.Windows.Forms; + +namespace TLO.Forms +{ + sealed partial class MainForm + { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.файлToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this._btSaveToFile = new System.Windows.Forms.ToolStripMenuItem(); + this._btLoadSettingsFromFile = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.ExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.отчетыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.SendReportsToForumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.CreateReportsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.задачиToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RuningStopingDistributionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.UpdateAll = new System.Windows.Forms.ToolStripMenuItem(); + this.UpdateCountSeedersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.UpdateListTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.UpdateKeepTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.LoadListKeepersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.ClearKeeperListsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ClearDatabaseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuTimerSetting = new System.Windows.Forms.ToolStripMenuItem(); + this.menuSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this._cbCategory = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this._tpReportDownloads = new System.Windows.Forms.TabPage(); + this.label7 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this._DateRegistration = new System.Windows.Forms.DateTimePicker(); + this.label5 = new System.Windows.Forms.Label(); + this._cbCountSeeders = new System.Windows.Forms.NumericUpDown(); + this._lbTotal = new System.Windows.Forms.Label(); + this._llUpdateTopicsByCategory = new System.Windows.Forms.LinkLabel(); + this._llUpdateCountSeedersByCategory = new System.Windows.Forms.LinkLabel(); + this._llUpdateDataDromTorrentClient = new System.Windows.Forms.LinkLabel(); + this.label4 = new System.Windows.Forms.Label(); + this.linkLabel5 = new System.Windows.Forms.LinkLabel(); + this.linkSetNewLabel = new System.Windows.Forms.LinkLabel(); + this._llSelectedTopicsDeleteFromBlackList = new System.Windows.Forms.LinkLabel(); + this._llSelectedTopicsToTorrentClient = new System.Windows.Forms.LinkLabel(); + this._llDownloadSelectTopics = new System.Windows.Forms.LinkLabel(); + this._llSelectedTopicsToBlackList = new System.Windows.Forms.LinkLabel(); + this._cbBlackList = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this._cbCategoryFilters = new System.Windows.Forms.ComboBox(); + this.label3 = new System.Windows.Forms.Label(); + this._dataGridTopicsList = new System.Windows.Forms.DataGridView(); + this.ColumnReport1DgvTopicID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvSelect = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.ColumnReport1DgvStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvName = new System.Windows.Forms.DataGridViewLinkColumn(); + this.ColumnReport1DgvAlternative = new System.Windows.Forms.DataGridViewLinkColumn(); + this.ColumnReport1DgvSeeders = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvAvgSeeders = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvRegTime = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvKeeperCount = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnReport1DgvBlack = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.tabReports = new System.Windows.Forms.TabPage(); + this.tabConsolidatedReport = new System.Windows.Forms.TabPage(); + this._txtConsolidatedReport = new System.Windows.Forms.TextBox(); + this.ConsolidatedTorrentClientsReport = new System.Windows.Forms.TabPage(); + this._tbConsolidatedTorrentClientsReport = new System.Windows.Forms.TextBox(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this._tcCetegoriesRootReports = new System.Windows.Forms.TabControl(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); + this.menuStrip1.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this._tpReportDownloads.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize) (this._cbCountSeeders)).BeginInit(); + ((System.ComponentModel.ISupportInitialize) (this._dataGridTopicsList)).BeginInit(); + this.tabConsolidatedReport.SuspendLayout(); + this.ConsolidatedTorrentClientsReport.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this._tcCetegoriesRootReports.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.файлToolStripMenuItem, this.отчетыToolStripMenuItem, this.задачиToolStripMenuItem, this.menuSettingsToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(984, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // файлToolStripMenuItem + // + this.файлToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.toolStripSeparator4, this._btSaveToFile, this._btLoadSettingsFromFile, this.toolStripSeparator3, this.ExitToolStripMenuItem}); + this.файлToolStripMenuItem.Name = "файлToolStripMenuItem"; + this.файлToolStripMenuItem.Size = new System.Drawing.Size(48, 20); + this.файлToolStripMenuItem.Text = "Файл"; + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(239, 6); + // + // _btSaveToFile + // + this._btSaveToFile.Name = "_btSaveToFile"; + this._btSaveToFile.Size = new System.Drawing.Size(242, 22); + this._btSaveToFile.Text = "Сохранить настройки в файл"; + this._btSaveToFile.Click += new System.EventHandler(this.MenuClick); + // + // _btLoadSettingsFromFile + // + this._btLoadSettingsFromFile.Name = "_btLoadSettingsFromFile"; + this._btLoadSettingsFromFile.Size = new System.Drawing.Size(242, 22); + this._btLoadSettingsFromFile.Text = "Загрузить настройки из файла"; + this._btLoadSettingsFromFile.Click += new System.EventHandler(this.MenuClick); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(239, 6); + // + // ExitToolStripMenuItem + // + this.ExitToolStripMenuItem.Name = "ExitToolStripMenuItem"; + this.ExitToolStripMenuItem.Size = new System.Drawing.Size(242, 22); + this.ExitToolStripMenuItem.Text = "Выход"; + this.ExitToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // отчетыToolStripMenuItem + // + this.отчетыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.SendReportsToForumToolStripMenuItem, this.CreateReportsToolStripMenuItem}); + this.отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; + this.отчетыToolStripMenuItem.Size = new System.Drawing.Size(60, 20); + this.отчетыToolStripMenuItem.Text = "Отчеты"; + // + // SendReportsToForumToolStripMenuItem + // + this.SendReportsToForumToolStripMenuItem.Name = "SendReportsToForumToolStripMenuItem"; + this.SendReportsToForumToolStripMenuItem.Size = new System.Drawing.Size(231, 22); + this.SendReportsToForumToolStripMenuItem.Text = "Отправить отчеты на форум"; + this.SendReportsToForumToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // CreateReportsToolStripMenuItem + // + this.CreateReportsToolStripMenuItem.Name = "CreateReportsToolStripMenuItem"; + this.CreateReportsToolStripMenuItem.Size = new System.Drawing.Size(231, 22); + this.CreateReportsToolStripMenuItem.Text = "Сформировать отчеты"; + this.CreateReportsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // задачиToolStripMenuItem + // + this.задачиToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.RuningStopingDistributionToolStripMenuItem, this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem, this.toolStripSeparator1, this.UpdateAll, this.UpdateCountSeedersToolStripMenuItem, this.UpdateListTopicsToolStripMenuItem, this.UpdateKeepTopicsToolStripMenuItem, this.LoadListKeepersToolStripMenuItem, this.toolStripSeparator2, this.ClearKeeperListsToolStripMenuItem, this.ClearDatabaseToolStripMenuItem, this.toolStripSeparator5, this.menuTimerSetting}); + this.задачиToolStripMenuItem.Name = "задачиToolStripMenuItem"; + this.задачиToolStripMenuItem.Size = new System.Drawing.Size(58, 20); + this.задачиToolStripMenuItem.Text = "Задачи"; + // + // RuningStopingDistributionToolStripMenuItem + // + this.RuningStopingDistributionToolStripMenuItem.Name = "RuningStopingDistributionToolStripMenuItem"; + this.RuningStopingDistributionToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.RuningStopingDistributionToolStripMenuItem.Text = "Запуск/Остановка раздач в торрент-клиентах"; + this.RuningStopingDistributionToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // CreateConsolidatedReportByTorrentClientsToolStripMenuItem + // + this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Name = "CreateConsolidatedReportByTorrentClientsToolStripMenuItem"; + this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Text = "Построить сводный отчет по торрент-клиентам"; + this.CreateConsolidatedReportByTorrentClientsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(376, 6); + // + // UpdateAll + // + this.UpdateAll.Name = "UpdateAll"; + this.UpdateAll.Size = new System.Drawing.Size(379, 22); + this.UpdateAll.Text = "Обновить всё и сразу"; + this.UpdateAll.Click += new System.EventHandler(this.MenuClick); + // + // UpdateCountSeedersToolStripMenuItem + // + this.UpdateCountSeedersToolStripMenuItem.Name = "UpdateCountSeedersToolStripMenuItem"; + this.UpdateCountSeedersToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.UpdateCountSeedersToolStripMenuItem.Text = "Обновить кол-во сидов по всем разделам"; + this.UpdateCountSeedersToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // UpdateListTopicsToolStripMenuItem + // + this.UpdateListTopicsToolStripMenuItem.Name = "UpdateListTopicsToolStripMenuItem"; + this.UpdateListTopicsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.UpdateListTopicsToolStripMenuItem.Text = "Обновить список топиков по всем разделам"; + this.UpdateListTopicsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // UpdateKeepTopicsToolStripMenuItem + // + this.UpdateKeepTopicsToolStripMenuItem.Name = "UpdateKeepTopicsToolStripMenuItem"; + this.UpdateKeepTopicsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.UpdateKeepTopicsToolStripMenuItem.Text = "Обновить списки хранимого по всем Torrent-клиентам"; + this.UpdateKeepTopicsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // LoadListKeepersToolStripMenuItem + // + this.LoadListKeepersToolStripMenuItem.Name = "LoadListKeepersToolStripMenuItem"; + this.LoadListKeepersToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.LoadListKeepersToolStripMenuItem.Text = "Обновить данные о других хранителях"; + this.LoadListKeepersToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(376, 6); + // + // ClearKeeperListsToolStripMenuItem + // + this.ClearKeeperListsToolStripMenuItem.Name = "ClearKeeperListsToolStripMenuItem"; + this.ClearKeeperListsToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.ClearKeeperListsToolStripMenuItem.Text = "Очистить списки хранителей со свод.значениями"; + this.ClearKeeperListsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // ClearDatabaseToolStripMenuItem + // + this.ClearDatabaseToolStripMenuItem.Name = "ClearDatabaseToolStripMenuItem"; + this.ClearDatabaseToolStripMenuItem.Size = new System.Drawing.Size(379, 22); + this.ClearDatabaseToolStripMenuItem.Text = "Очистить списки разделов (удалить топики)"; + this.ClearDatabaseToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(376, 6); + // + // menuTimerSetting + // + this.menuTimerSetting.Checked = true; + this.menuTimerSetting.CheckOnClick = true; + this.menuTimerSetting.CheckState = System.Windows.Forms.CheckState.Checked; + this.menuTimerSetting.Name = "menuTimerSetting"; + this.menuTimerSetting.Size = new System.Drawing.Size(379, 22); + this.menuTimerSetting.Text = "Таймер"; + // + // menuSettingsToolStripMenuItem + // + this.menuSettingsToolStripMenuItem.Image = ((System.Drawing.Image) (resources.GetObject("menuSettingsToolStripMenuItem.Image"))); + this.menuSettingsToolStripMenuItem.Name = "menuSettingsToolStripMenuItem"; + this.menuSettingsToolStripMenuItem.Size = new System.Drawing.Size(95, 20); + this.menuSettingsToolStripMenuItem.Text = "Настройки"; + this.menuSettingsToolStripMenuItem.Click += new System.EventHandler(this.MenuClick); + // + // _cbCategory + // + this._cbCategory.Anchor = ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this._cbCategory.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this._cbCategory.FormattingEnabled = true; + this._cbCategory.Location = new System.Drawing.Point(117, 27); + this._cbCategory.Name = "_cbCategory"; + this._cbCategory.Size = new System.Drawing.Size(855, 21); + this._cbCategory.TabIndex = 1; + this._cbCategory.SelectionChangeCommitted += new System.EventHandler(this.SelectionChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 30); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(99, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Выберите раздел:"; + // + // tabControl1 + // + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Controls.Add(this._tpReportDownloads); + this.tabControl1.Controls.Add(this.tabReports); + this.tabControl1.Controls.Add(this.tabConsolidatedReport); + this.tabControl1.Controls.Add(this.ConsolidatedTorrentClientsReport); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Location = new System.Drawing.Point(0, 54); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(984, 483); + this.tabControl1.TabIndex = 3; + // + // _tpReportDownloads + // + this._tpReportDownloads.Controls.Add(this.label7); + this._tpReportDownloads.Controls.Add(this.label6); + this._tpReportDownloads.Controls.Add(this.button1); + this._tpReportDownloads.Controls.Add(this._DateRegistration); + this._tpReportDownloads.Controls.Add(this.label5); + this._tpReportDownloads.Controls.Add(this._cbCountSeeders); + this._tpReportDownloads.Controls.Add(this._lbTotal); + this._tpReportDownloads.Controls.Add(this._llUpdateTopicsByCategory); + this._tpReportDownloads.Controls.Add(this._llUpdateCountSeedersByCategory); + this._tpReportDownloads.Controls.Add(this._llUpdateDataDromTorrentClient); + this._tpReportDownloads.Controls.Add(this.label4); + this._tpReportDownloads.Controls.Add(this.linkLabel5); + this._tpReportDownloads.Controls.Add(this.linkSetNewLabel); + this._tpReportDownloads.Controls.Add(this._llSelectedTopicsDeleteFromBlackList); + this._tpReportDownloads.Controls.Add(this._llSelectedTopicsToTorrentClient); + this._tpReportDownloads.Controls.Add(this._llDownloadSelectTopics); + this._tpReportDownloads.Controls.Add(this._llSelectedTopicsToBlackList); + this._tpReportDownloads.Controls.Add(this._cbBlackList); + this._tpReportDownloads.Controls.Add(this.label2); + this._tpReportDownloads.Controls.Add(this._cbCategoryFilters); + this._tpReportDownloads.Controls.Add(this.label3); + this._tpReportDownloads.Controls.Add(this._dataGridTopicsList); + this._tpReportDownloads.Location = new System.Drawing.Point(4, 22); + this._tpReportDownloads.Name = "_tpReportDownloads"; + this._tpReportDownloads.Padding = new System.Windows.Forms.Padding(3); + this._tpReportDownloads.Size = new System.Drawing.Size(976, 457); + this._tpReportDownloads.TabIndex = 2; + this._tpReportDownloads.Text = "Обработка раздела"; + this._tpReportDownloads.UseVisualStyleBackColor = true; + // + // label7 + // + this.label7.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(780, 414); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(44, 13); + this.label7.TabIndex = 35; + this.label7.Text = "Прочее"; + // + // label6 + // + this.label6.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(780, 202); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(116, 13); + this.label6.TabIndex = 34; + this.label6.Text = "Действия по разделу"; + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.button1.Location = new System.Drawing.Point(780, 430); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(128, 23); + this.button1.TabIndex = 33; + this.button1.Text = "Неизвестные в файл"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.ExportUnknown_Click); + // + // _DateRegistration + // + this._DateRegistration.Format = System.Windows.Forms.DateTimePickerFormat.Short; + this._DateRegistration.Location = new System.Drawing.Point(63, 6); + this._DateRegistration.Name = "_DateRegistration"; + this._DateRegistration.Size = new System.Drawing.Size(93, 20); + this._DateRegistration.TabIndex = 32; + this._DateRegistration.ValueChanged += new System.EventHandler(this.SelectionChanged); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(5, 9); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(51, 13); + this.label5.TabIndex = 31; + this.label5.Text = "Дата до:"; + // + // _cbCountSeeders + // + this._cbCountSeeders.Location = new System.Drawing.Point(245, 6); + this._cbCountSeeders.Minimum = new decimal(new int[] {1, 0, 0, -2147483648}); + this._cbCountSeeders.Name = "_cbCountSeeders"; + this._cbCountSeeders.Size = new System.Drawing.Size(40, 20); + this._cbCountSeeders.TabIndex = 30; + this._cbCountSeeders.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this._cbCountSeeders.ValueChanged += new System.EventHandler(this.SelectionChanged); + // + // _lbTotal + // + this._lbTotal.AutoSize = true; + this._lbTotal.Location = new System.Drawing.Point(5, 30); + this._lbTotal.Name = "_lbTotal"; + this._lbTotal.Size = new System.Drawing.Size(40, 13); + this._lbTotal.TabIndex = 29; + this._lbTotal.Text = "Итого:"; + // + // _llUpdateTopicsByCategory + // + this._llUpdateTopicsByCategory.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._llUpdateTopicsByCategory.AutoSize = true; + this._llUpdateTopicsByCategory.Location = new System.Drawing.Point(780, 269); + this._llUpdateTopicsByCategory.Name = "_llUpdateTopicsByCategory"; + this._llUpdateTopicsByCategory.Size = new System.Drawing.Size(154, 13); + this._llUpdateTopicsByCategory.TabIndex = 28; + this._llUpdateTopicsByCategory.TabStop = true; + this._llUpdateTopicsByCategory.Text = "Обновить список по разделу"; + this._llUpdateTopicsByCategory.Click += new System.EventHandler(this.LinkClick); + // + // _llUpdateCountSeedersByCategory + // + this._llUpdateCountSeedersByCategory.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._llUpdateCountSeedersByCategory.AutoSize = true; + this._llUpdateCountSeedersByCategory.Location = new System.Drawing.Point(780, 246); + this._llUpdateCountSeedersByCategory.Name = "_llUpdateCountSeedersByCategory"; + this._llUpdateCountSeedersByCategory.Size = new System.Drawing.Size(184, 13); + this._llUpdateCountSeedersByCategory.TabIndex = 27; + this._llUpdateCountSeedersByCategory.TabStop = true; + this._llUpdateCountSeedersByCategory.Text = "Обновить кол-во сидов по разделу"; + this._llUpdateCountSeedersByCategory.Click += new System.EventHandler(this.LinkClick); + // + // _llUpdateDataDromTorrentClient + // + this._llUpdateDataDromTorrentClient.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._llUpdateDataDromTorrentClient.AutoSize = true; + this._llUpdateDataDromTorrentClient.Location = new System.Drawing.Point(780, 292); + this._llUpdateDataDromTorrentClient.Name = "_llUpdateDataDromTorrentClient"; + this._llUpdateDataDromTorrentClient.Size = new System.Drawing.Size(184, 13); + this._llUpdateDataDromTorrentClient.TabIndex = 26; + this._llUpdateDataDromTorrentClient.TabStop = true; + this._llUpdateDataDromTorrentClient.Text = "Обновить инф. из торрент-клиента"; + this._llUpdateDataDromTorrentClient.Click += new System.EventHandler(this.LinkClick); + // + // label4 + // + this.label4.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(780, 35); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(141, 13); + this.label4.TabIndex = 23; + this.label4.Text = "Действия с выделенными"; + // + // linkLabel5 + // + this.linkLabel5.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.linkLabel5.AutoSize = true; + this.linkLabel5.Location = new System.Drawing.Point(780, 126); + this.linkLabel5.Name = "linkLabel5"; + this.linkLabel5.Size = new System.Drawing.Size(186, 13); + this.linkLabel5.TabIndex = 22; + this.linkLabel5.TabStop = true; + this.linkLabel5.Text = "Удалить из Torrent-клиента+файлы"; + this.linkLabel5.Visible = false; + // + // linkSetNewLabel + // + this.linkSetNewLabel.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.linkSetNewLabel.AutoSize = true; + this.linkSetNewLabel.Location = new System.Drawing.Point(780, 104); + this.linkSetNewLabel.Name = "linkSetNewLabel"; + this.linkSetNewLabel.Size = new System.Drawing.Size(100, 13); + this.linkSetNewLabel.TabIndex = 21; + this.linkSetNewLabel.TabStop = true; + this.linkSetNewLabel.Text = "Установить метку"; + this.linkSetNewLabel.Click += new System.EventHandler(this.LinkClick); + // + // _llSelectedTopicsDeleteFromBlackList + // + this._llSelectedTopicsDeleteFromBlackList.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._llSelectedTopicsDeleteFromBlackList.AutoSize = true; + this._llSelectedTopicsDeleteFromBlackList.Location = new System.Drawing.Point(780, 170); + this._llSelectedTopicsDeleteFromBlackList.Name = "_llSelectedTopicsDeleteFromBlackList"; + this._llSelectedTopicsDeleteFromBlackList.Size = new System.Drawing.Size(147, 13); + this._llSelectedTopicsDeleteFromBlackList.TabIndex = 20; + this._llSelectedTopicsDeleteFromBlackList.TabStop = true; + this._llSelectedTopicsDeleteFromBlackList.Text = "Удалить из черного списка"; + this._llSelectedTopicsDeleteFromBlackList.Click += new System.EventHandler(this.LinkClick); + // + // _llSelectedTopicsToTorrentClient + // + this._llSelectedTopicsToTorrentClient.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._llSelectedTopicsToTorrentClient.AutoSize = true; + this._llSelectedTopicsToTorrentClient.Location = new System.Drawing.Point(780, 81); + this._llSelectedTopicsToTorrentClient.Name = "_llSelectedTopicsToTorrentClient"; + this._llSelectedTopicsToTorrentClient.Size = new System.Drawing.Size(141, 13); + this._llSelectedTopicsToTorrentClient.TabIndex = 19; + this._llSelectedTopicsToTorrentClient.TabStop = true; + this._llSelectedTopicsToTorrentClient.Text = "Добавить в Torrent-клиент"; + this._llSelectedTopicsToTorrentClient.Click += new System.EventHandler(this.LinkClick); + // + // _llDownloadSelectTopics + // + this._llDownloadSelectTopics.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._llDownloadSelectTopics.AutoSize = true; + this._llDownloadSelectTopics.Location = new System.Drawing.Point(780, 58); + this._llDownloadSelectTopics.Name = "_llDownloadSelectTopics"; + this._llDownloadSelectTopics.Size = new System.Drawing.Size(122, 13); + this._llDownloadSelectTopics.TabIndex = 18; + this._llDownloadSelectTopics.TabStop = true; + this._llDownloadSelectTopics.Text = "Скачать Torrent-файлы"; + this._llDownloadSelectTopics.Click += new System.EventHandler(this.LinkClick); + // + // _llSelectedTopicsToBlackList + // + this._llSelectedTopicsToBlackList.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._llSelectedTopicsToBlackList.AutoSize = true; + this._llSelectedTopicsToBlackList.Location = new System.Drawing.Point(780, 148); + this._llSelectedTopicsToBlackList.Name = "_llSelectedTopicsToBlackList"; + this._llSelectedTopicsToBlackList.Size = new System.Drawing.Size(145, 13); + this._llSelectedTopicsToBlackList.TabIndex = 17; + this._llSelectedTopicsToBlackList.TabStop = true; + this._llSelectedTopicsToBlackList.Text = "Добавить в черный список"; + this._llSelectedTopicsToBlackList.Click += new System.EventHandler(this.LinkClick); + // + // _cbBlackList + // + this._cbBlackList.AutoSize = true; + this._cbBlackList.Location = new System.Drawing.Point(522, 9); + this._cbBlackList.Name = "_cbBlackList"; + this._cbBlackList.Size = new System.Drawing.Size(105, 17); + this._cbBlackList.TabIndex = 14; + this._cbBlackList.Text = "Черный список"; + this._cbBlackList.UseVisualStyleBackColor = true; + this._cbBlackList.CheckedChanged += new System.EventHandler(this.SelectionChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(290, 9); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(50, 13); + this.label2.TabIndex = 12; + this.label2.Text = "Фильтр:"; + // + // _cbCategoryFilters + // + this._cbCategoryFilters.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this._cbCategoryFilters.FormattingEnabled = true; + this._cbCategoryFilters.Items.AddRange(new object[] {"Все", "Не скачан торрент и нет хранителя", "Не скачан торрент", "Храню", "Храню и есть хранитель", "Не храню", "Скачиваю раздачу", "Я релизер", "Не скачано"}); + this._cbCategoryFilters.Location = new System.Drawing.Point(346, 5); + this._cbCategoryFilters.Name = "_cbCategoryFilters"; + this._cbCategoryFilters.Size = new System.Drawing.Size(170, 21); + this._cbCategoryFilters.TabIndex = 11; + this._cbCategoryFilters.SelectionChangeCommitted += new System.EventHandler(this.SelectionChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(162, 9); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 13); + this.label3.TabIndex = 9; + this.label3.Text = "Кол-во сидов:"; + // + // _dataGridTopicsList + // + this._dataGridTopicsList.AllowUserToAddRows = false; + this._dataGridTopicsList.AllowUserToDeleteRows = false; + this._dataGridTopicsList.AllowUserToResizeRows = false; + this._dataGridTopicsList.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this._dataGridTopicsList.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this._dataGridTopicsList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {this.ColumnReport1DgvTopicID, this.ColumnReport1DgvSelect, this.ColumnReport1DgvStatus, this.ColumnReport1DgvSize, this.ColumnReport1DgvName, this.ColumnReport1DgvAlternative, this.ColumnReport1DgvSeeders, this.ColumnReport1DgvAvgSeeders, this.ColumnReport1DgvRegTime, this.ColumnReport1DgvKeeperCount, this.ColumnReport1DgvBlack}); + this._dataGridTopicsList.Location = new System.Drawing.Point(8, 48); + this._dataGridTopicsList.MultiSelect = false; + this._dataGridTopicsList.Name = "_dataGridTopicsList"; + this._dataGridTopicsList.RowHeadersVisible = false; + this._dataGridTopicsList.Size = new System.Drawing.Size(766, 403); + this._dataGridTopicsList.TabIndex = 0; + this._dataGridTopicsList.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ContentClick); + this._dataGridTopicsList.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._dgvReportDownloads_CellDoubleClick); + this._dataGridTopicsList.Click += new System.EventHandler(this._dgvReportDownloads_Click); + // + // ColumnReport1DgvTopicID + // + this.ColumnReport1DgvTopicID.DataPropertyName = "TopicID"; + this.ColumnReport1DgvTopicID.HeaderText = "Column1"; + this.ColumnReport1DgvTopicID.Name = "ColumnReport1DgvTopicID"; + this.ColumnReport1DgvTopicID.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvTopicID.Visible = false; + this.ColumnReport1DgvTopicID.Width = 10; + // + // ColumnReport1DgvSelect + // + this.ColumnReport1DgvSelect.DataPropertyName = "Checked"; + this.ColumnReport1DgvSelect.FalseValue = "false"; + this.ColumnReport1DgvSelect.HeaderText = ""; + this.ColumnReport1DgvSelect.Name = "ColumnReport1DgvSelect"; + this.ColumnReport1DgvSelect.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.ColumnReport1DgvSelect.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvSelect.TrueValue = "true"; + this.ColumnReport1DgvSelect.Width = 19; + // + // ColumnReport1DgvStatus + // + this.ColumnReport1DgvStatus.DataPropertyName = "StatusToString"; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter; + this.ColumnReport1DgvStatus.DefaultCellStyle = dataGridViewCellStyle1; + this.ColumnReport1DgvStatus.HeaderText = ""; + this.ColumnReport1DgvStatus.Name = "ColumnReport1DgvStatus"; + this.ColumnReport1DgvStatus.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvStatus.Width = 19; + // + // ColumnReport1DgvSize + // + this.ColumnReport1DgvSize.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader; + this.ColumnReport1DgvSize.DataPropertyName = "SizeToString"; + this.ColumnReport1DgvSize.HeaderText = "Размер"; + this.ColumnReport1DgvSize.Name = "ColumnReport1DgvSize"; + this.ColumnReport1DgvSize.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvSize.Width = 71; + // + // ColumnReport1DgvName + // + this.ColumnReport1DgvName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.ColumnReport1DgvName.DataPropertyName = "Name"; + this.ColumnReport1DgvName.HeaderText = "Наименование"; + this.ColumnReport1DgvName.Name = "ColumnReport1DgvName"; + this.ColumnReport1DgvName.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.ColumnReport1DgvName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + // + // ColumnReport1DgvAlternative + // + this.ColumnReport1DgvAlternative.DataPropertyName = "Alternative"; + this.ColumnReport1DgvAlternative.HeaderText = "Альтернативы"; + this.ColumnReport1DgvAlternative.Name = "ColumnReport1DgvAlternative"; + this.ColumnReport1DgvAlternative.ReadOnly = true; + this.ColumnReport1DgvAlternative.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.ColumnReport1DgvAlternative.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvAlternative.Width = 105; + // + // ColumnReport1DgvSeeders + // + this.ColumnReport1DgvSeeders.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader; + this.ColumnReport1DgvSeeders.DataPropertyName = "Seeders"; + this.ColumnReport1DgvSeeders.HeaderText = "Сиды"; + this.ColumnReport1DgvSeeders.Name = "ColumnReport1DgvSeeders"; + this.ColumnReport1DgvSeeders.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvSeeders.Width = 59; + // + // ColumnReport1DgvAvgSeeders + // + this.ColumnReport1DgvAvgSeeders.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.ColumnReport1DgvAvgSeeders.DataPropertyName = "AvgSeeders"; + this.ColumnReport1DgvAvgSeeders.HeaderText = "Ср. кол-во сидов"; + this.ColumnReport1DgvAvgSeeders.Name = "ColumnReport1DgvAvgSeeders"; + this.ColumnReport1DgvAvgSeeders.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvAvgSeeders.Width = 85; + // + // ColumnReport1DgvRegTime + // + this.ColumnReport1DgvRegTime.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.ColumnReport1DgvRegTime.DataPropertyName = "RegTimeToString"; + this.ColumnReport1DgvRegTime.HeaderText = "Дата"; + this.ColumnReport1DgvRegTime.Name = "ColumnReport1DgvRegTime"; + this.ColumnReport1DgvRegTime.ReadOnly = true; + this.ColumnReport1DgvRegTime.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvRegTime.Width = 80; + // + // ColumnReport1DgvKeeperCount + // + this.ColumnReport1DgvKeeperCount.DataPropertyName = "KeeperCount"; + dataGridViewCellStyle2.Format = "N0"; + this.ColumnReport1DgvKeeperCount.DefaultCellStyle = dataGridViewCellStyle2; + this.ColumnReport1DgvKeeperCount.HeaderText = "Хранителей"; + this.ColumnReport1DgvKeeperCount.MaxInputLength = 64; + this.ColumnReport1DgvKeeperCount.Name = "ColumnReport1DgvKeeperCount"; + this.ColumnReport1DgvKeeperCount.ReadOnly = true; + this.ColumnReport1DgvKeeperCount.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.ColumnReport1DgvKeeperCount.ToolTipText = "Всего хранителей (без учёта Вас)"; + this.ColumnReport1DgvKeeperCount.Width = 92; + // + // ColumnReport1DgvBlack + // + this.ColumnReport1DgvBlack.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.ColumnReport1DgvBlack.DataPropertyName = "IsBlackList"; + this.ColumnReport1DgvBlack.FalseValue = "false"; + this.ColumnReport1DgvBlack.HeaderText = "Black"; + this.ColumnReport1DgvBlack.Name = "ColumnReport1DgvBlack"; + this.ColumnReport1DgvBlack.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.ColumnReport1DgvBlack.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic; + this.ColumnReport1DgvBlack.TrueValue = "true"; + this.ColumnReport1DgvBlack.Visible = false; + this.ColumnReport1DgvBlack.Width = 40; + // + // tabReports + // + this.tabReports.Location = new System.Drawing.Point(4, 22); + this.tabReports.Name = "tabReports"; + this.tabReports.Padding = new System.Windows.Forms.Padding(3); + this.tabReports.Size = new System.Drawing.Size(976, 457); + this.tabReports.TabIndex = 3; + this.tabReports.Text = "Отчеты"; + this.tabReports.UseVisualStyleBackColor = true; + // + // tabConsolidatedReport + // + this.tabConsolidatedReport.Controls.Add(this._txtConsolidatedReport); + this.tabConsolidatedReport.Location = new System.Drawing.Point(4, 22); + this.tabConsolidatedReport.Name = "tabConsolidatedReport"; + this.tabConsolidatedReport.Size = new System.Drawing.Size(976, 457); + this.tabConsolidatedReport.TabIndex = 0; + this.tabConsolidatedReport.Text = "Сводный отчет"; + this.tabConsolidatedReport.UseVisualStyleBackColor = true; + // + // _txtConsolidatedReport + // + this._txtConsolidatedReport.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this._txtConsolidatedReport.Location = new System.Drawing.Point(0, 0); + this._txtConsolidatedReport.Multiline = true; + this._txtConsolidatedReport.Name = "_txtConsolidatedReport"; + this._txtConsolidatedReport.Size = new System.Drawing.Size(976, 461); + this._txtConsolidatedReport.TabIndex = 0; + // + // ConsolidatedTorrentClientsReport + // + this.ConsolidatedTorrentClientsReport.Controls.Add(this._tbConsolidatedTorrentClientsReport); + this.ConsolidatedTorrentClientsReport.Location = new System.Drawing.Point(4, 22); + this.ConsolidatedTorrentClientsReport.Name = "ConsolidatedTorrentClientsReport"; + this.ConsolidatedTorrentClientsReport.Padding = new System.Windows.Forms.Padding(3); + this.ConsolidatedTorrentClientsReport.Size = new System.Drawing.Size(976, 457); + this.ConsolidatedTorrentClientsReport.TabIndex = 5; + this.ConsolidatedTorrentClientsReport.Text = "Отчет torrent-клиентов"; + this.ConsolidatedTorrentClientsReport.UseVisualStyleBackColor = true; + // + // _tbConsolidatedTorrentClientsReport + // + this._tbConsolidatedTorrentClientsReport.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this._tbConsolidatedTorrentClientsReport.Location = new System.Drawing.Point(0, 0); + this._tbConsolidatedTorrentClientsReport.Multiline = true; + this._tbConsolidatedTorrentClientsReport.Name = "_tbConsolidatedTorrentClientsReport"; + this._tbConsolidatedTorrentClientsReport.ReadOnly = true; + this._tbConsolidatedTorrentClientsReport.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this._tbConsolidatedTorrentClientsReport.Size = new System.Drawing.Size(976, 454); + this._tbConsolidatedTorrentClientsReport.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this._tcCetegoriesRootReports); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(976, 457); + this.tabPage1.TabIndex = 4; + this.tabPage1.Text = "Отчет по разделам"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // _tcCetegoriesRootReports + // + this._tcCetegoriesRootReports.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this._tcCetegoriesRootReports.Controls.Add(this.tabPage2); + this._tcCetegoriesRootReports.Controls.Add(this.tabPage3); + this._tcCetegoriesRootReports.Location = new System.Drawing.Point(1, 1); + this._tcCetegoriesRootReports.Name = "_tcCetegoriesRootReports"; + this._tcCetegoriesRootReports.SelectedIndex = 0; + this._tcCetegoriesRootReports.Size = new System.Drawing.Size(975, 459); + this._tcCetegoriesRootReports.TabIndex = 0; + // + // tabPage2 + // + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(967, 433); + this.tabPage2.TabIndex = 0; + this.tabPage2.Text = "tabPage2"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // tabPage3 + // + this.tabPage3.Location = new System.Drawing.Point(4, 22); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3); + this.tabPage3.Size = new System.Drawing.Size(967, 433); + this.tabPage3.TabIndex = 1; + this.tabPage3.Text = "tabPage3"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.toolStripStatusLabel1, this.toolStripProgressBar1}); + this.statusStrip1.Location = new System.Drawing.Point(0, 539); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(984, 22); + this.statusStrip1.TabIndex = 4; + this.statusStrip1.Text = "statusStrip1"; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(0, 17); + // + // toolStripProgressBar1 + // + this.toolStripProgressBar1.Name = "toolStripProgressBar1"; + this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16); + this.toolStripProgressBar1.Visible = false; + // + // MainForm + // + this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange; + this.ClientSize = new System.Drawing.Size(984, 561); + this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.label1); + this.Controls.Add(this._cbCategory); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.MaximumSize = new System.Drawing.Size(3840, 2160); + this.MinimumSize = new System.Drawing.Size(1000, 600); + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "TLO"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FireFormClosing); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.tabControl1.ResumeLayout(false); + this._tpReportDownloads.ResumeLayout(false); + this._tpReportDownloads.PerformLayout(); + ((System.ComponentModel.ISupportInitialize) (this._cbCountSeeders)).EndInit(); + ((System.ComponentModel.ISupportInitialize) (this._dataGridTopicsList)).EndInit(); + this.tabConsolidatedReport.ResumeLayout(false); + this.tabConsolidatedReport.PerformLayout(); + this.ConsolidatedTorrentClientsReport.ResumeLayout(false); + this.ConsolidatedTorrentClientsReport.PerformLayout(); + this.tabPage1.ResumeLayout(false); + this._tcCetegoriesRootReports.ResumeLayout(false); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + } + + private System.Windows.Forms.ToolStripMenuItem _btLoadSettingsFromFile; + private System.Windows.Forms.ToolStripMenuItem _btSaveToFile; + private System.Windows.Forms.CheckBox _cbBlackList; + private System.Windows.Forms.ComboBox _cbCategory; + private System.Windows.Forms.ComboBox _cbCategoryFilters; + private System.Windows.Forms.NumericUpDown _cbCountSeeders; + private System.Windows.Forms.DataGridView _dataGridTopicsList; + private System.Windows.Forms.DateTimePicker _DateRegistration; + private System.Windows.Forms.Label _lbTotal; + private System.Windows.Forms.LinkLabel _llDownloadSelectTopics; + private System.Windows.Forms.LinkLabel _llSelectedTopicsDeleteFromBlackList; + private System.Windows.Forms.LinkLabel _llSelectedTopicsToBlackList; + private System.Windows.Forms.LinkLabel _llSelectedTopicsToTorrentClient; + private System.Windows.Forms.LinkLabel _llUpdateCountSeedersByCategory; + private System.Windows.Forms.LinkLabel _llUpdateDataDromTorrentClient; + private System.Windows.Forms.LinkLabel _llUpdateTopicsByCategory; + private System.Windows.Forms.TextBox _tbConsolidatedTorrentClientsReport; + private System.Windows.Forms.TabControl _tcCetegoriesRootReports; + private System.Windows.Forms.TabPage _tpReportDownloads; + private System.Windows.Forms.TextBox _txtConsolidatedReport; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.ToolStripMenuItem ClearDatabaseToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem ClearKeeperListsToolStripMenuItem; + private System.Windows.Forms.DataGridViewLinkColumn ColumnReport1DgvAlternative; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvAvgSeeders; + private System.Windows.Forms.DataGridViewCheckBoxColumn ColumnReport1DgvBlack; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvKeeperCount; + private System.Windows.Forms.DataGridViewLinkColumn ColumnReport1DgvName; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvRegTime; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvSeeders; + private System.Windows.Forms.DataGridViewCheckBoxColumn ColumnReport1DgvSelect; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvSize; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvStatus; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnReport1DgvTopicID; + private System.Windows.Forms.TabPage ConsolidatedTorrentClientsReport; + private System.Windows.Forms.ToolStripMenuItem CreateConsolidatedReportByTorrentClientsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem CreateReportsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem ExitToolStripMenuItem; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.LinkLabel linkLabel5; + private System.Windows.Forms.LinkLabel linkSetNewLabel; + private System.Windows.Forms.ToolStripMenuItem LoadListKeepersToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem menuSettingsToolStripMenuItem; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuTimerSetting; + private System.Windows.Forms.ToolStripMenuItem RuningStopingDistributionToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem SendReportsToForumToolStripMenuItem; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.TabPage tabConsolidatedReport; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.TabPage tabReports; + private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; + private System.Windows.Forms.ToolStripMenuItem UpdateAll; + private System.Windows.Forms.ToolStripMenuItem UpdateCountSeedersToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem UpdateKeepTopicsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem UpdateListTopicsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem задачиToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem отчетыToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem файлToolStripMenuItem; + + #endregion + } +} \ No newline at end of file diff --git a/TLO/Forms/MainForm.cs b/TLO/Forms/MainForm.cs new file mode 100644 index 0000000..14e247d --- /dev/null +++ b/TLO/Forms/MainForm.cs @@ -0,0 +1,1100 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows.Forms; +using NLog; +using TLO.Clients; +using TLO.Info; +using TLO.Tools; + +namespace TLO.Forms +{ + internal sealed partial class MainForm : Form + { + private readonly Dictionary> _backgroundWorkers = + new Dictionary>(); + + private readonly BindingSource _categorySource = new BindingSource(); + + private readonly string _headText; + private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly Timer _tmr; + private readonly BindingSource _topicsSource = new BindingSource(); + private DateTime _lastRunTimer = DateTime.Now; + + public MainForm() + { + InitializeComponent(); + menuTimerSetting.CheckStateChanged += (sender, args) => + { + if (menuTimerSetting.Checked) + { + _lastRunTimer = DateTime.Now; + if (!_tmr.Enabled) _tmr.Start(); + } + else + { + if (_tmr.Enabled) _tmr.Stop(); + } + }; + var locationBinding = new Binding("Location", Properties.Settings.Default, + "WindowLocation", true, DataSourceUpdateMode.OnPropertyChanged); + var sizeBinding = new Binding("Size", Properties.Settings.Default, + "WindowSize", true, DataSourceUpdateMode.OnPropertyChanged); + locationBinding.ControlUpdateMode = ControlUpdateMode.Never; + sizeBinding.ControlUpdateMode = ControlUpdateMode.Never; + var bindingAdded = false; + + void SyncBindings() + { + if (WindowState == FormWindowState.Normal) + { + if (bindingAdded) return; + DataBindings.Add(locationBinding); + DataBindings.Add(sizeBinding); + bindingAdded = true; + } + else + { + if (!bindingAdded) return; + DataBindings.Remove(locationBinding); + DataBindings.Remove(sizeBinding); + bindingAdded = false; + } + } + + Resize += (sender, args) => { SyncBindings(); }; + HandleCreated += (sender, args) => Location = Properties.Settings.Default.WindowLocation; + HandleCreated += (sender, args) => SyncBindings(); + + _DateRegistration.Value = DateTime.Now.AddDays(-30.0); + Text = _headText = + $"TLO {FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion}"; + _cbCountSeeders.Value = new decimal(0); + _cbCategoryFilters.SelectedItem = "Не скачан торрент и нет хранителя"; + _categorySource.Clear(); + _categorySource.DataSource = ClientLocalDb.Current.GetCategoriesEnable(true); + _categorySource.CurrentChanged += SelectionChanged; + _cbCategory.DataSource = _categorySource; + if (_categorySource.Count > 0) + _categorySource.Position = 1; + _topicsSource.CurrentChanged += SelectionChanged; + _dataGridTopicsList.AutoGenerateColumns = false; + _dataGridTopicsList.ClearSelection(); + _dataGridTopicsList.DataSource = _topicsSource; + Type dgvType = _dataGridTopicsList.GetType(); + PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", + BindingFlags.Instance | BindingFlags.NonPublic); + pi.SetValue(_dataGridTopicsList, true, null); + Disposed += MainForm_Disposed; + _tmr = new Timer(); + _tmr.Tick += tmr_Tick; + _tmr.Interval = 1000; + _tmr.Start(); + TrayObject.TrayIcon.ContextMenu.MenuItems.Add(new MenuItem(@"Закрыть", DoQuit)); + WriteReports(); + } + + private new Point Location + { + set + { + if ( + value.X > 0 && + value.Y > 0 && + value.X < SystemInformation.VirtualScreen.Size.Width - 100 && + value.Y < SystemInformation.VirtualScreen.Size.Height - 100 + ) + base.Location = value; + } + } + + private void MenuClick(object sender, EventArgs e) + { + try + { + if (sender == menuSettingsToolStripMenuItem) + { + if (new SettingsForm().ShowDialog() == DialogResult.OK) + { + _categorySource.Clear(); + _categorySource.DataSource = null; + _categorySource.DataSource = ClientLocalDb.Current.GetCategoriesEnable(true); + _categorySource.Position = 0; + } + } + else if (sender == UpdateAll) + { + DwCreateAndRun(WorkerMethods.bwUpdateTopicsByCategories, + "Полное обновление информации о топиках (раздачах) по всем категориям...", + ClientLocalDb.Current.GetCategoriesEnable()); + DwCreateAndRun(WorkerMethods.bwUpdateHashFromAllTorrentClients, + "Полное обновление информации из Torrent-клиентов..."); + DwCreateAndRun(WorkerMethods.bwUpdateCountSeedersByAllCategories, + "Обновление кол-ва сидов на раздачах...", sender); + DwCreateAndRun(WorkerMethods.bwUpdateKeepersByAllCategories, + "Обновление данных о хранителях...", sender); + } + else if (sender == UpdateCountSeedersToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwUpdateCountSeedersByAllCategories, + "Обновление кол-ва сидов на раздачах...", sender); + } + else if (sender == UpdateListTopicsToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwUpdateTopicsByCategories, + "Полное обновление информации о топиках (раздачах) по всем категориям...", + ClientLocalDb.Current.GetCategoriesEnable()); + } + else if (sender == UpdateKeepTopicsToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwUpdateHashFromAllTorrentClients, + "Полное обновление информации из Torrent-клиентов..."); + } + else if (sender == ClearDatabaseToolStripMenuItem) + { + if (MessageBox.Show( + "Вы пытаетесь очистить базу данны от текущих данных (статистику и информацию о топиках).\r\n Продолжить?", + "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, + MessageBoxDefaultButton.Button2) != DialogResult.Yes) + return; + ClientLocalDb.Current.ClearDatabase(); + } + else if (sender == ClearKeeperListsToolStripMenuItem) + { + if (MessageBox.Show("Вы пытаетесь очистить базу данны от данных других хранителей.\r\n Продолжить?", + "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, + MessageBoxDefaultButton.Button2) != DialogResult.Yes) + return; + ClientLocalDb.Current.ClearKeepers(); + SelectionChanged(_categorySource, null); + } + else if (sender == SendReportsToForumToolStripMenuItem) + { + if (MessageBox.Show( + "Отправка отчетов на форум может продолжаться продолжительное время.\r\nПродолжить?", + "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, + MessageBoxDefaultButton.Button2) != DialogResult.Yes) + return; + DwCreateAndRun(WorkerMethods.bwSendReports, + "Отправка отчетов на форум...", + this); + } + else if (sender == CreateReportsToolStripMenuItem) + { + if (MessageBox.Show( + "Сборка отчетов может продолжаться продолжительное время и потребуется обновить список раздач и информацию из торрент-клиентов.\r\n Продолжить?", + "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, + MessageBoxDefaultButton.Button2) != DialogResult.Yes) + return; + DwCreateAndRun(WorkerMethods.bwUpdateCountSeedersByAllCategories, + "Обновление кол-ва сидов на раздачах...", sender); + DwCreateAndRun(WorkerMethods.bwUpdateHashFromAllTorrentClients, + "Обновление информации из Torrent-клиентов...", sender); + } + else if (sender == RuningStopingDistributionToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwUpdateCountSeedersByAllCategories, + "Обновление кол-ва сидов на раздачах...", sender); + DwCreateAndRun(WorkerMethods.bwRuningAndStopingDistributions, + "Обновление информации из Torrent-клиентов...", sender); + DwCreateAndRun(WorkerMethods.bwCreateReportsTorrentClients, + "Построение сводного отчета по торрент-клиентам...", sender); + } + else if (sender == CreateConsolidatedReportByTorrentClientsToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwCreateReportsTorrentClients, + "Построение сводного отчета по торрент-клиентам...", sender); + } + else if (sender == LoadListKeepersToolStripMenuItem) + { + DwCreateAndRun(WorkerMethods.bwUpdateKeepersByAllCategories, + "Обновление данных о хранителях...", sender); + } + else if (sender == ExitToolStripMenuItem) + { + DoQuit(sender, e); + } + else if (sender == _btSaveToFile) + { + SaveSetingsToFile(); + } + else if (sender == _btLoadSettingsFromFile) + { + ReadSettingsFromFile(); + } + } + catch (Exception ex) + { + Cursor.Current = Cursors.Default; + MessageBox.Show(ex.Message); + } + + Cursor.Current = Cursors.Default; + } + + private void tmr_Tick(object sender, EventArgs e) + { + if (_backgroundWorkers.Count > 0) + { + Text = $@"{_headText} (Выполняются задачи...)"; + TrayObject.TrayIcon.Text = $@"{_headText} (Выполняются задачи...)"; + } + else + { + var lastRunTimer = _lastRunTimer; + var now = DateTime.Now; + var dateTime1 = now.AddMinutes(-Settings.Current.PeriodRunAndStopTorrents); + var timeSpan = lastRunTimer - dateTime1; + if (timeSpan.TotalSeconds > 0.0) + { + Text = $"{_headText} ({timeSpan:hh\\:mm\\:ss})"; + TrayObject.TrayIcon.BalloonTipText = + TrayObject.TrayIcon.Text = $"{_headText} ({timeSpan:hh\\:mm\\:ss})"; + if (Properties.Settings.Default.NotificationInTray) + { + TrayObject.TrayIcon.ShowBalloonTip(7); + } + } + else + { + try + { + var lastUpdateTopics = Settings.Current.LastUpdateTopics; + now = DateTime.Now; + var dateTime2 = now.AddDays(-1.0); + if (lastUpdateTopics < dateTime2) + { + DwCreateAndRun(WorkerMethods.bwUpdateTopicsByCategories, + "Полное обновление информации о топиках (раздачах) по всем категориям...", + ClientLocalDb.Current.GetCategoriesEnable()); + DwCreateAndRun(WorkerMethods.bwUpdateKeepersByAllCategories, + "Обновление данных о хранителях...", sender); + var current = Settings.Current; + now = DateTime.Now; + var date = now.Date; + current.LastUpdateTopics = date; + Settings.Current.Save(); + } + else + { + DwCreateAndRun( + WorkerMethods.bwUpdateCountSeedersByAllCategories, + "Обновление информации о кол-ве сидов на раздачах...", sender); + } + + DwCreateAndRun(WorkerMethods.bwRuningAndStopingDistributions, + "Запуск/Остановка раздач в Torrent-клиентах...", sender); + DwCreateAndRun(WorkerMethods.bwCreateReportsTorrentClients, + "Построение сводного отчета по торрент-клиентам...", sender); + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Debug(ex, ex.Message); + } + + _lastRunTimer = DateTime.Now; + } + } + } + + private void MainForm_Disposed(object sender, EventArgs e) + { + _tmr.Stop(); + _tmr.Dispose(); + } + + private void DoQuit(object sender, EventArgs e) + { + Application.Exit(); + } + + private void SelectionChanged(object sender, EventArgs e) + { + if (sender == _categorySource || sender == _cbCountSeeders || sender == _cbBlackList || + sender == _cbCategoryFilters || sender == _DateRegistration) + { + _topicsSource.Clear(); + if (_categorySource.Current != null) + { + var current = _categorySource.Current as Category; + var num = (int) _cbCountSeeders.Value; + var regTime = _DateRegistration.Value; + var isKeep = new bool?(); + var isKeepers = new bool?(); + var isDownload = new bool?(); + var isBlack = new bool?(); + var isPoster = new bool?(); + var selectedItem = _cbCategoryFilters.SelectedItem as string; + if (!string.IsNullOrWhiteSpace(selectedItem)) + switch (selectedItem) + { + case "Есть хранитель": + isKeepers = true; + break; + case "Не скачан торрент": + isDownload = false; + isKeep = false; + break; + case "Не скачан торрент и есть хранитель": + isDownload = false; + isKeepers = true; + break; + case "Не скачан торрент и нет хранителя": + isDownload = false; + isKeepers = false; + break; + case "Не скачано": + isDownload = false; + break; + case "Не храню": + isKeep = false; + break; + case "Скачиваю раздачу": + isDownload = true; + isKeep = false; + break; + case "Храню": + isKeep = true; + break; + case "Храню и есть хранитель": + isKeep = true; + isKeepers = true; + break; + case "Я релизер": + isPoster = false; + break; + } + + List source; + + if (current.CategoryID != -1) + { + isBlack = _cbBlackList.Checked; + var topicInfoList = new List(); + source = !Settings.Current.IsAvgCountSeeders + ? ClientLocalDb.Current.GetTopics(regTime, current.CategoryID, + num > -1 ? num : new int?(), new int?(), isKeep, isKeepers, isDownload, + isBlack, + isPoster) + : ClientLocalDb.Current.GetTopics(regTime, current.CategoryID, new int?(), + num > -1 ? num : new int?(), isKeep, isKeepers, isDownload, isBlack, + isPoster); + } + else + { + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + var inner = ClientLocalDb.Current.GetTopicsByCategory(-1) + .Where(x => !x.IsBlackList); + var dictionary = ClientLocalDb.Current.GetCategories() + .ToDictionary(x => x.CategoryID, x => x); + source = new List(); + foreach (var torrentClientInfo in torrentClients) + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + { + var array1 = torrentClient.GetAllTorrentHash().GroupJoin(inner, t => t.Hash, + b => b.Hash, (t, bt) => new + { + t, bt + }).SelectMany(param1 => param1.bt.DefaultIfEmpty(), (param1, b) => + { + var num3 = b != null ? b.CategoryID : -1; + var size = param1.t.Size; + var isRun = param1.t.IsRun; + int num4; + if (!isRun.HasValue) + { + num4 = -1; + } + else + { + isRun = param1.t.IsRun; + num4 = isRun.Value ? 1 : 0; + } + + var num5 = param1.t.IsPause ? 1 : 0; + var num6 = b == null ? -1 : b.Seeders; + TopicInfo a; + if (b == null) + { + a = (TopicInfo) param1.t.Clone(); + a.CategoryID = num3; + a.Name2 = param1.t.TorrentName; + a.Size = size; + a.IsRun = isRun; + a.IsPause = num5 != 0; + a.Seeders = num6; + a.Label = param1.t.Label; + return a; + } + + a = b; + + return a; + /*{ + CategoryID = num3, + Name = _param1.t.TorrentName, + Size = size, + IsRun = num4, + IsPause = num5 != 0, + Seeders = num6, + Label = _param1.t.Label + };*/ + }); + source.AddRange(array1.Where(x => x.CategoryID == -1).ToArray()); + } + } + } + + _lbTotal.Text = string.Format("Кол-во: {0}; Размер: {1}", source.Count(), + TopicInfo.sizeToString(source.Sum(x => x.Size))); + _topicsSource.DataSource = source; + } + } + + if (sender != _categorySource || _categorySource.Current == null) + return; + tabReports.Controls.Clear(); + var reports = + ClientLocalDb.Current.GetReports((_categorySource.Current as Category).CategoryID); + if (reports.Count() > 0) + { + var size = tabReports.Size; + var tabControl = new TabControl + { + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, + Location = new Point(0, 0), + SelectedIndex = 0, + Size = new Size(size.Width, size.Height) + }; + tabReports.Controls.Add(tabControl); + foreach (var keyValuePair in reports + .OrderBy( + x => x.Key.Item2)) + if (!(keyValuePair.Value.Item2 == "Резерв") && !(keyValuePair.Value.Item2 == "Удалено")) + { + var tabPage = new TabPage(); + var textBox = new TextBox(); + tabPage.Location = new Point(4, 22); + tabPage.Padding = new Padding(3); + tabPage.Text = string.Format("Сидируемое: отчет № {0}", keyValuePair.Key.Item2); + if (keyValuePair.Key.Item2 == 0) + tabPage.Text = "Шапка сидируемого"; + tabPage.UseVisualStyleBackColor = true; + tabPage.AutoScroll = true; + textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | + AnchorStyles.Right; + textBox.Location = new Point(0, 0); + textBox.Multiline = true; + textBox.ReadOnly = true; + textBox.ScrollBars = ScrollBars.Both; + textBox.Size = new Size(size.Width - 8, size.Height - 20); + textBox.Text = keyValuePair.Value.Item2; + tabControl.Controls.Add(tabPage); + tabPage.Controls.Add(textBox); + } + } + else + { + var size = tabReports.Size; + var tabControl = new TabControl(); + tabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + tabControl.Location = new Point(0, 0); + tabControl.SelectedIndex = 0; + tabControl.Size = new Size(size.Width, size.Height); + tabReports.Controls.Add(tabControl); + var tabPage = new TabPage(); + var textBox = new TextBox(); + tabControl.Controls.Add(tabPage); + tabPage.Controls.Add(textBox); + tabPage.Location = new Point(4, 22); + tabPage.Padding = new Padding(3); + tabPage.Text = "Для информации"; + tabPage.UseVisualStyleBackColor = true; + textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + textBox.Location = new Point(0, 0); + textBox.Multiline = true; + textBox.ReadOnly = true; + textBox.ScrollBars = ScrollBars.Both; + textBox.Size = new Size(size.Width - 8, size.Height - 20); + textBox.Text = + "Здесь должен быть отчет о сидируемом, но его нет.\r\nВозможные причины: сервис не успел обработать задачи сервера на скачивание страниц, прочитать torrent-файлы или не смог подключиться к torrent-клиенту\r\n\r\nЕсли на вкладке \"Не скачано\" есть раздачи которые Вы храните, то попробуйте сформировать отчет принудительно из пункта меню"; + } + } + + private void LinkClick(object sender, EventArgs e) + { + if (_backgroundWorkers.Count != 0 && + MessageBox.Show("Выполняются другие задачи. Добавить в очередь новое?", "Внимание", + MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != + DialogResult.Yes) + return; + Cursor.Current = Cursors.WaitCursor; + try + { + if (!(_categorySource.Current is Category current)) + return; + + if (sender == _llUpdateCountSeedersByCategory) + { + UpdaterMethods.UpdateSeedersByCategory(current); + } + else if (sender == _llUpdateTopicsByCategory) + { + DwCreateAndRun(WorkerMethods.bwUpdateTopicsByCategory, + "Обновление списков по разделу...", current); + } + else if (sender == _llUpdateDataDromTorrentClient) + { + UpdaterMethods.UpdateHashFromClients(current.TorrentClientUID); + } + else if (sender == _llDownloadSelectTopics) + { + DwCreateAndRun(WorkerMethods.bwDownloadTorrentFiles, + "Скачиваются выделеные торрент-файлы в каталог...", + new Tuple, MainForm>( + (_topicsSource.DataSource as List) + .Where(x => x.Checked).ToList(), this)); + } + else if (sender == _llSelectedTopicsToTorrentClient) + { + DwCreateAndRun(WorkerMethods.bwSendTorrentFileToTorrentClient, + "Скачиваются и добавляются в торрент-клиент выделенные раздачи...", + new Tuple, Category>(this, + (_topicsSource.DataSource as List) + .Where(x => x.Checked).ToList(), current)); + DwCreateAndRun( + WorkerMethods.bwUpdateHashFromTorrentClientsByCategoryUID, + "Обновляем список раздач из торрент-клиента...", current); + } + else if (sender == _llSelectedTopicsToBlackList) + { + var list = (_topicsSource.DataSource as List) + .Where(x => x.Checked).ToList(); + list.ForEach(x => x.IsBlackList = true); + ClientLocalDb.Current.SaveTopicInfo(list); + } + else if (sender == _llSelectedTopicsDeleteFromBlackList) + { + var list = (_topicsSource.DataSource as List) + .Where(x => x.Checked).ToList(); + list.ForEach(x => x.IsBlackList = false); + ClientLocalDb.Current.SaveTopicInfo(list); + } + else if (sender == linkSetNewLabel) + { + var getLabelName = new GetLabelName(); + getLabelName.Value = string.IsNullOrWhiteSpace(current.Label) ? current.FullName : current.Label; + if (getLabelName.ShowDialog() == DialogResult.OK) + DwCreateAndRun(WorkerMethods.bwSetLabels, + "Установка пользовательских меток...", + new Tuple, string>(this, + (_topicsSource.DataSource as List) + .Where(x => x.Checked).ToList(), + getLabelName.Value)); + } + + SelectionChanged(_categorySource, null); + } + catch (Exception ex) + { + _logger.Error(ex); + var num = (int) MessageBox.Show("Произошла ошибка:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + + Cursor.Current = Cursors.Default; + } + + private void ContentClick(object sender, DataGridViewCellEventArgs e) + { + if (_dataGridTopicsList.Columns[e.ColumnIndex].DataPropertyName == "Name") + { + var nullable = _dataGridTopicsList.Rows[e.RowIndex].Cells[0].Value as int?; + if (!nullable.HasValue) + return; + if (Program.IsRunningOnMono()) + { + Process.Start("xdg-open", string.Format("https://{1}/forum/viewtopic.php?t={0}", nullable.Value, + Settings.Current.HostRuTrackerOrg)); + } + else + { + Process.Start(string.Format("https://{1}/forum/viewtopic.php?t={0}", nullable.Value, + Settings.Current.HostRuTrackerOrg)); + } + } + else + { + if (_dataGridTopicsList.Columns[e.ColumnIndex].DataPropertyName != "Alternative") + return; + var topicId = _dataGridTopicsList.Rows[e.RowIndex].Cells[0].Value as int?; + if (!topicId.HasValue) + return; + if (!(_topicsSource.DataSource is List dataSource)) + return; + var topicInfo = dataSource.FirstOrDefault(x => x.TopicID == topicId.Value); + if (topicInfo == null) + return; + var num1 = topicInfo.Name.IndexOf('/'); + string str1; + if (topicInfo.Name.IndexOf(']') > num1 && num1 != -1) + str1 = topicInfo.Name.Split('/').FirstOrDefault(); + else if (topicInfo.Name.IndexOf(']') < num1 && num1 != -1) + str1 = topicInfo.Name.Split('/').FirstOrDefault().Split(']')[1]; + else if (num1 == -1 && topicInfo.Name.IndexOf('[') < 5 && topicInfo.Name.IndexOf('[') != -1) + str1 = topicInfo.Name.Split(']')[1].Split('[').FirstOrDefault(); + else if (num1 == -1 && topicInfo.Name.IndexOf('[') != -1) + str1 = topicInfo.Name.Split('[').FirstOrDefault(); + else + str1 = topicInfo.Name.Split('[').FirstOrDefault(); + var num2 = topicInfo.Name.IndexOf('[', num1 > -1 ? num1 : 0); + if (num2 < 5) + { + var startIndex = topicInfo.Name.IndexOf(']') + 1; + num2 = topicInfo.Name.IndexOf('[', startIndex); + } + + var str2 = topicInfo.Name.Substring(num2 == -1 ? 0 : num2 + 1); + if (!string.IsNullOrWhiteSpace(str2)) + str2 = str2.Split(new char[3] + { + ',', + ' ', + ']' + }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(str2)) + str1 = str1 + " " + str2; + if (Program.IsRunningOnMono()) + { + Process.Start("xdg-open", string.Format( + "https://{2}/forum/tracker.php?f={0}&nm={1}", + topicInfo.CategoryID, str1, Settings.Current.HostRuTrackerOrg)); + } + else + { + Process.Start(string.Format( + "https://{2}/forum/tracker.php?f={0}&nm={1}", + topicInfo.CategoryID, str1, Settings.Current.HostRuTrackerOrg)); + } + } + } + + private void DwCreateAndRun(DoWorkEventHandler e, string comment = "...", object argument = null) + { + var key = new BackgroundWorker + { + WorkerReportsProgress = true, + WorkerSupportsCancellation = true + }; + key.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted; + key.ProgressChanged += backgroundWorker1_ProgressChanged; + key.DoWork += e; + _backgroundWorkers.Add(key, new Tuple(DateTime.Now, argument, comment)); + if (_backgroundWorkers.Count != 1) + return; + key.RunWorkerAsync(argument); + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + toolStripProgressBar1.Value = 0; + toolStripProgressBar1.Visible = false; + toolStripStatusLabel1.Text = ""; + toolStripStatusLabel1.Visible = false; + statusStrip1.Refresh(); + if (sender != null && sender is BackgroundWorker && + _backgroundWorkers.ContainsKey(sender as BackgroundWorker)) + { + var key = sender as BackgroundWorker; + if (_backgroundWorkers.ContainsKey(key)) + _backgroundWorkers.Remove(key); + key.Dispose(); + } + + if (e.Result != null) + _logger.Info(e.Result); + if (_backgroundWorkers.Count > 0) + { + // запуск следующей задачи. + var keyValuePair = _backgroundWorkers.OrderBy(x => x.Value.Item1).First(); + keyValuePair.Key.RunWorkerAsync(keyValuePair.Value.Item2); + } + else + { + // записываем окончательные изменения в БД после выполнения последней задачи. + SelectionChanged(_categorySource, null); + WriteReports(); + ClientLocalDb.Current.SaveToDatabase(); + } + + GC.Collect(); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + if (sender != null && sender is BackgroundWorker && + _backgroundWorkers.ContainsKey(sender as BackgroundWorker)) + { + toolStripStatusLabel1.Text = _backgroundWorkers[sender as BackgroundWorker].Item3; + toolStripProgressBar1.Visible = true; + toolStripStatusLabel1.Visible = true; + statusStrip1.Refresh(); + } + + toolStripProgressBar1.Value = + e.ProgressPercentage < 0 || e.ProgressPercentage > 100 ? 100 : e.ProgressPercentage; + } + + private void _dgvReportDownloads_CellDoubleClick(object sender, DataGridViewCellEventArgs e) + { + var column = _dataGridTopicsList.Columns[e.ColumnIndex]; + if (column == ColumnReport1DgvSelect) + { + var dataSource = _topicsSource.DataSource as List; + if (dataSource == null) + return; + var list = dataSource.ToList(); + list.ForEach(x => + { + var topicInfo = x; + topicInfo.Checked = !topicInfo.Checked; + }); + _topicsSource.Clear(); + _topicsSource.DataSource = list; + } + else + { + var sortedColumn = _dataGridTopicsList.SortedColumn; + var sortOrder = + column.HeaderCell.SortGlyphDirection == SortOrder.None || + column.HeaderCell.SortGlyphDirection == SortOrder.Descending + ? SortOrder.Ascending + : SortOrder.Descending; + if (column == null) + { + var num = (int) MessageBox.Show("Select a single column and try again.", "Error: Invalid Selection", + MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + else + { + var dataSource = _topicsSource.DataSource as List; + if (dataSource == null) + return; + var list1 = dataSource.ToList(); + List list2; + if (column == ColumnReport1DgvSize) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1.OrderBy( + d => d.Size) + : list1.OrderByDescending( + d => d.Size)).ToList(); + } + else if (column == ColumnReport1DgvName) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1.OrderBy( + d => d.Name) + : list1.OrderByDescending( + d => d.Name)).ToList(); + } + else if (column == ColumnReport1DgvSeeders) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1 + .OrderBy(d => d.Seeders) + .ThenBy(d => Name) + : list1 + .OrderByDescending(d => d.Seeders) + .ThenBy(d => Name)) + .ToList(); + } + else if (column == ColumnReport1DgvAvgSeeders) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1 + .OrderBy(d => d.AvgSeeders) + .ThenBy(d => Name) + : list1 + .OrderByDescending( + d => d.AvgSeeders) + .ThenBy(d => Name)) + .ToList(); + } + else if (column == ColumnReport1DgvRegTime) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1 + .OrderBy(d => d.RegTime) + .ThenBy(d => Name) + : list1 + .OrderByDescending( + d => d.RegTime) + .ThenBy(d => Name)) + .ToList(); + } + else if (column == ColumnReport1DgvKeeperCount) + { + list2 = (sortOrder == SortOrder.Ascending + ? list1 + .OrderBy(d => d.KeeperCount) + .ThenBy(d => Name) + : list1 + .OrderByDescending(d => d.KeeperCount) + .ThenBy(d => Name)) + .ToList(); + } + else + { + if (column != ColumnReport1DgvStatus) + return; + list2 = (sortOrder == SortOrder.Ascending + ? list1 + .OrderBy(d => d.StatusToString) + .ThenBy(d => Name) + : list1 + .OrderByDescending( + d => d.StatusToString) + .ThenBy(d => Name)) + .ToList(); + } + + _topicsSource.Clear(); + _topicsSource.DataSource = list2; + column.HeaderCell.SortGlyphDirection = sortOrder; + } + } + } + + private void _dgvReportDownloads_Click(object sender, EventArgs e) + { + if (_dataGridTopicsList.Columns.GetColumnCount(DataGridViewElementStates.Selected) == 1) + { + var selectedColumn = _dataGridTopicsList.SelectedColumns[0]; + } + + Console.WriteLine(""); + } + + private void WriteReports() + { + Reports.CreateReportByRootCategories(); + _tcCetegoriesRootReports.Controls.Clear(); + var reports = ClientLocalDb.Current.GetReports(0); + var str1 = reports + .Where( + x => x.Key.Item2 == 0) + .Select( + x => x.Value.Item2) + .FirstOrDefault(); + _txtConsolidatedReport.Text = string.IsNullOrWhiteSpace(str1) ? string.Empty : str1; + var str2 = reports + .Where( + x => x.Key.Item2 == 1) + .Select( + x => x.Value.Item2) + .FirstOrDefault(); + _tbConsolidatedTorrentClientsReport.Text = string.IsNullOrWhiteSpace(str2) ? string.Empty : str2; + var categories = ClientLocalDb.Current.GetCategories() + .Where(x => x.CategoryID > 100000); + var size = _tcCetegoriesRootReports.Size; + foreach (var category in categories) + { + var str3 = ClientLocalDb.Current.GetReports(category.CategoryID) + .Where( + x => x.Key.Item2 == 0) + .Select( + x => x.Value.Item2) + .FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(str3)) + { + var tabPage = new TabPage(); + var textBox = new TextBox(); + tabPage.Location = new Point(4, 22); + tabPage.Padding = new Padding(3); + tabPage.Text = category.Name; + tabPage.UseVisualStyleBackColor = true; + tabPage.AutoScroll = true; + tabPage.Size = size; + textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + textBox.Location = new Point(0, 0); + textBox.Multiline = true; + textBox.ReadOnly = true; + textBox.ScrollBars = ScrollBars.Both; + textBox.Size = new Size(size.Width - 8, size.Height - 20); + textBox.Text = str3; + _tcCetegoriesRootReports.Controls.Add(tabPage); + tabPage.Controls.Add(textBox); + } + } + } + + private void SaveSetingsToFile() + { + try + { + var empty = string.Empty; + var saveFileDialog = new SaveFileDialog(); + saveFileDialog.DefaultExt = "tloback"; + saveFileDialog.Filter = "Файл архивных настроек|*.tloback"; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + var fileName = saveFileDialog.FileName; + if (string.IsNullOrWhiteSpace(fileName)) + return; + using (var fileStream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write)) + { + using (var binaryWriter = new BinaryWriter(fileStream, Encoding.UTF8)) + { + foreach (var torrentClient in ClientLocalDb.Current.GetTorrentClients()) + { + binaryWriter.Write("TorrentClientInfo"); + binaryWriter.Write(torrentClient.UID.ToString()); + binaryWriter.Write(torrentClient.Name); + binaryWriter.Write(torrentClient.Type); + binaryWriter.Write(torrentClient.ServerName); + binaryWriter.Write(torrentClient.ServerPort); + binaryWriter.Write(torrentClient.UserName); + binaryWriter.Write(torrentClient.UserPassword); + } + + foreach (var category in ClientLocalDb.Current.GetCategoriesEnable()) + { + binaryWriter.Write("Category"); + binaryWriter.Write(category.CategoryID); + binaryWriter.Write(category.CountSeeders); + binaryWriter.Write(category.TorrentClientUID.ToString()); + binaryWriter.Write(category.Folder); + binaryWriter.Write(category.CreateSubFolder); + binaryWriter.Write(category.IsSaveTorrentFiles); + binaryWriter.Write(category.IsSaveWebPage); + binaryWriter.Write(category.Label); + } + + var cats = ClientLocalDb.Current.GetCategoriesEnable() + .Select(x => x.CategoryID).ToArray(); + var reports = + ClientLocalDb.Current.GetReports(new int?()); + foreach (var keyValuePair in reports + .Where( + x => + cats.Contains(x.Key.Item1))) + { + binaryWriter.Write("Report"); + binaryWriter.Write(keyValuePair.Key.Item1); + binaryWriter.Write(keyValuePair.Key.Item2); + binaryWriter.Write(keyValuePair.Value.Item1); + } + } + } + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Trace(ex.StackTrace); + } + } + + private void ReadSettingsFromFile() + { + try + { + var empty = string.Empty; + var openFileDialog = new OpenFileDialog(); + openFileDialog.DefaultExt = "tloback"; + openFileDialog.Filter = "Файл архивных настроек|*.tloback"; + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + var fileName = openFileDialog.FileName; + if (string.IsNullOrWhiteSpace(fileName)) + return; + var torrentClientInfoList = new List(); + var categoryList = new List(); + var result = new List>(); + using (var fileStream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Read)) + { + using (var binaryReader = new BinaryReader(fileStream)) + { + while (binaryReader.BaseStream.Length != binaryReader.BaseStream.Position) + { + var str = binaryReader.ReadString(); + if (!(str == "TorrentClientInfo")) + { + if (!(str == "Category")) + { + if (str == "Report") + result.Add(new Tuple(binaryReader.ReadInt32(), + binaryReader.ReadInt32(), binaryReader.ReadString())); + } + else + { + var category = new Category + { + CategoryID = binaryReader.ReadInt32(), + IsEnable = true, + CountSeeders = binaryReader.ReadInt32(), + TorrentClientUID = Guid.Parse(binaryReader.ReadString()), + Folder = binaryReader.ReadString(), + CreateSubFolder = binaryReader.ReadInt32(), + IsSaveTorrentFiles = binaryReader.ReadBoolean(), + IsSaveWebPage = binaryReader.ReadBoolean(), + Label = binaryReader.ReadString() + }; + categoryList.Add(category); + } + } + else + { + var torrentClientInfo = new TorrentClientInfo + { + UID = Guid.Parse(binaryReader.ReadString()), + Name = binaryReader.ReadString(), + Type = binaryReader.ReadString(), + ServerName = binaryReader.ReadString(), + ServerPort = binaryReader.ReadInt32(), + UserName = binaryReader.ReadString(), + UserPassword = binaryReader.ReadString() + }; + torrentClientInfoList.Add(torrentClientInfo); + } + } + + ClientLocalDb.Current.SaveTorrentClients(torrentClientInfoList); + ClientLocalDb.Current.CategoriesSave(categoryList); + ClientLocalDb.Current.SaveSettingsReport(result); + ClientLocalDb.Current.SaveToDatabase(); + } + } + } + catch (Exception ex) + { + _logger.Error(ex.Message); + _logger.Trace(ex.StackTrace); + } + } + + private void FireFormClosing(object sender, FormClosingEventArgs e) + { + Properties.Settings.Default.Save(); + } + + private void ExportUnknown_Click(object sender, EventArgs e) + { + DwCreateAndRun( + WorkerMethods.bwCreateUnknownTorrentsReport, + "Формирование отчета", + this + ); + } + } +} \ No newline at end of file diff --git a/TLO/Forms/MainForm.resx b/TLO/Forms/MainForm.resx new file mode 100644 index 0000000..6d2afb1 --- /dev/null +++ b/TLO/Forms/MainForm.resx @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAXdJREFUOE+l + lcsuREEQho/7jo3E0gNIbPAISFiyxxqvMfas2dq6hh2v4BYex/f1OZX0nEscM3/yzfSpruqeqq7TU/TQ + LnxX7GgYV9ewWuG4tybhHL7gRAOagSdYqXCsTemj7wUY25ATZzAL93ALP3AJ8xWOTf0G9NHXGGOHNAHu + poPyewvi1+TS5lzua2xDphC71rVYUZe+xkSJGjIVdw/twzu8wGs11hbaBmNaZSrWZzo9FcUhPMBSeirl + +BEO0lMZY52HSmOf2Q6e4JUG5KlZFw+irgVwLk7WGGNdI/XpJ6zDGuislkGnLj2DPspNjXWNDw1+xILx + i0ZZcAPSgnnK9pkaK+WQLZAfyhH0ORRjhg4ll2/HZjlMskXewLYRx3sQssU62+YU7uA/jT0HNvZxespU + f/V0dPdIP5c2s8h9jW3IF3wAsauptF0O2ixNZGNM43JQU+CEu0UKFtsWabu+LJG+xhjbW7bDSBdsl+wt + W0P++Asoil9fO1VEwIG+2QAAAABJRU5ErkJggg== + + + + 116, 17 + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAObk5ACjn6AEgn5/EY6Ki1SYl5dGe317AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANfU1AKTj5AeXVtbT0pISI1EQUPGTUpL7GZjYq5lZWIKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv4 + +QC9u7sEoJ6fDnN0dhJzdXk0aGhqc29qa9hKR0j1Yl9g/X15ev+JhIT/WVVT7FxcWDb6//sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5uXlAZua + mwiNjIwfcm9zU1pYW5Jyb3DITExP1FBPU+1paGr6ko2O/paRkv+alJX/l5GS/4aBgf9QTUr7T09Kj35+ + fQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz9/AC7u7sEkpGUEYaE + hTdkZWdvU1NWrkdHSd9KSk72Wlhc/YaBgv+Lhoj/lpCR/5uVlf+YkpP/jYeI/3t1df9iXlz/ZWBh/0hD + Qv48ODjvT0xMTn17ewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJAJWSlAeRj5Afd3R2UVla + XY5HSU3JNzk87k1OUPpxb3L+jIiL/5uWmP+emJn/n5mZ/5mSk/+LhYb/eHNy/2ZgYP9XUVD/RkE//0Q/ + Pf9dWFj/Uk5O/0I9PP5IRUWtZ2VlCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfnJ4WVVNWnkhJ + S95PUFP1ZWVo/Xx4e/+FgYP/mpOW/6Gbm/+gmpv/m5SV/4B6e/9vaGj/VE1N/1dQUP90cHD/RD49/y0n + Jv8kIB//MSwr/zk0M/9XU1P/SUVD/0pGRexWVFQ7k5OTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSg + oz55dXfyi4eK/56am/+inZ7/oJqb/5mTlP+Nhoj/c21u/2ZhYf9lXl//WlRU/3Jyc/9dWVj/RUA+/3Fs + bP9NSEj/Ih0c/x0YF/8dGBj/IBsa/y0oJ/9LRUT/RD8//URBQZdjY2EGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAApqSlXp6ZmveblZb/lI2O/4R9fv9zbW3/c3Bx/6Ggov9RUlT/ODc4/1VTVP9NS03/Z2lt/3Jw + cf9bVFL/VU9P/zw3OP8eGRn/GRUU/x0bI/8jICj/My0s/1VOTf9KRUT/QT085FJRUCsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKh4iLcWxs/G1nZ/9WUE//V09P/0xHR/94dXz/w8jQ/73DzP+vtr3/t7/I/2Jl + av8oKCr/IB4f/0pERP9GQD//JyYr/yUjI/8jISD/KSYu/z86Pv9RS0j/WVJR/1BKSv9CPj37Q0BAg2Vl + ZAMAAAAAAAAAAAAAAAAAAAAAAAAAAHFubm5jXl70c21u/3FsbP9STkz/WFVW/5+hqP/K0tz/0dnj/9Ha + 4//M1d//maCp/z5ASf8YFhf/JCAg/zczMv82Mzb/OTU0/0Q+Pv9BOzr/SUJC/09HR/9VTk7/U05N/0ZB + QP4/PDvaWVhXIAAAAAAAAAAAAAAAAAAAAAAAAAAAjoqKDHBqaqs3MzP9YFxd/zs2Nf94dnn/ztbf/8rT + 3P/Q2eL/ztbf/7G3vv+MkJj/PD5G/xcWGP8WFRj/HB4r/y80Tf9AOjn/Pzo5/z45OP8/Ojn/Qz49/0ZB + QP9KRUX/SENC/z87OvlLSUhye3l5AgAAAAAAAAAAAAAAAAAAAACtq6oAgHt6Oj04OOgkHx//NTEw/5me + ov/R2eH/vsbP/8rT3P98foP/c25x/3d2e/9GUF3/ISIv/xwhMv8kLUv/Iic1/yMhIv8eGxz/Gxka/xkY + GP8bGBj/Ih4f/zAsLP9DPj7/RUA//k1KScxsamkXAAAAAAAAAAAAAAAAAAAAAAAAAACVj48FaGJiiyAb + HPshHh7/oaWq/9be5v/P1+D/wsrT/2tpbP+0s7b/yMjJ/7e6vf+MlKP/TVZn/z1FT/8xQE3/L0FS/yM0 + RP8gLDj/FBkh/wwND/8TEBD/FRIS/yAcHP9EPz7/SUVE9lNSUV+Ji4oAAAAAAAAAAAAAAAAAAAAAAAAA + AACEgIAjR0JD1hMREf56fYH/1d7n/9Xe5//L1N3/k5Wa/7q5u/+4t7r/7u7v/+Lh4/+Aj5z/iZmo/1l+ + oP8/g8D/OIPE/zV8u/8vbaj/JFSC/xs1T/8SFh7/GhcX/0I9Pf9GQkH+SEZFvGloaA8AAAAAAAAAAAAA + AAAAAAAAAAAAAJ6cnAJybW1sKCMj901OUf/T2+L/ztfg/8vU3f+wt7//R0xR/3SWr/+m0e3/r9Xt/7PG + 0v+Pnqn/xszQ/3qOo/9GgLT/OITH/zOAxP8yer//MHS5/ytim/8zQ1n/Uk9P/1xXV/9GQkHyWldXTYWE + hAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGMjBNMSEi+JSQk/oKEh//L0tn/zNXd/6Ottv9diqr/bbbo/2e0 + 6f9hr+f/Y67l/3u24v+ZxOP/scTR/5mnsf9mk7v/OYLF/zN+wv8xeb7/L3W7/zBtrf86VnX/Q0JE/05K + Sv5QTk6saGZmCQAAAAAAAAAAAAAAAAAAAAAAAAAAm5eWAHBsbEw4MzTvDg4O/0BAQv9ucXX/cZav/3m9 + 7f9zu+7/bLfr/2Wy6f9creb/Vafi/1Ch3v9UoNr/YKLX/3Gl0f9hkr//PoTD/zJ9wf8xeL7/L3S6/y5w + s/81VXj/VlVX/2RiY+1hYGA9pqenAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIiICWJeXaAgHR39RkFC/zAw + M/9Scon/aaDF/3Gz4P9vt+n/arbr/2Ox6f9ereX/YKDQ/2+fxf9PfKL/OG6e/0CFwv89icv/NIHG/zF9 + wf8xeL3/L3S6/y1wsf9AVGv/cnBx/VtZWZp+fX0GAAAAAAAAAAAAAAAAAAAAAAAAAAC0tLQAe3h4MFhU + VOFoY2P+ZGdr/1VkcP9FVWL/PlNj/0dke/9bkrv/aLLn/2qcw/9/pcn/XYu7/1OEuP86Xob/J0hq/zd6 + tv84hsv/NIHG/zJ9wv8weL//Lna8/zJnnf9UVVj/WlhY5nd3dy/Y2NgAAAAAAAAAAAAAAAAAAAAAAAAA + AACSj5AEbGdoflNQUPlnhJj/icXt/4PB6f96uOL/cq3V/22t2P9rsOL/RH21/1+Pw/+brcr/k6vP/4Wh + xP9Oh8D/O2+g/z2Lz/84hsv/NIHI/zB8xf8ueML/LnO4/0JMWv9dWVn7bGlqiYyLiwQAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACDf38cYVxbzWWCl/6LyfH/iMnx/4PG8f9+wvD/dr/u/2ew5f9RjMn/hpi8/8jA + 1f+xsLj/srnV/3efyf9Rk9D/QZHT/zuL0P82hs3/M4HJ/zB8xv8ud77/Okpc/0lGRf52cnLcnp2dHwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6OjgFsaWheVmRw9IfC6v+LyvL/h8fx/4HE8f98wfD/cbnr/0uN + zf9dib3/oJ3E/7m92P+esc7/Y5rR/06Z3P9Fldj/P5DU/zqL0f82hs3/M4HK/zB4vP85RU//ODUz/42K + jPixr7NkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIF/fg5TU1a0aZGt/YzJ8v+JyfL/hcby/4DD + 8f96v+//arHl/1SV0f9llsn/UojD/2ye0P9Qmdv/Tp3e/0ma2/9ElNf/Po/T/zqK0P82hc7/M2uf/zw7 + Pf8/Ozr/iYaK/a6ssZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnJaXAGpoaUJCSVHrdaXH/4rJ + 8v+Jx/P/hMXy/37C8f95vu//cbns/2av5v9eqeL/XKnj/1io5P9SouH/TZ3e/0iY2/9Ck9b/PY7S/zqC + wP85Slv/IyEg/yAdHf9ZVFf+paOmjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhoOEB1tY + WJY5Qkn8bZq4/4jH7/+Hx/L/gsTw/33B8P93vu7/cLns/2q26v9jsej/XKzm/1am4/9RoOD/S5vd/0WW + 2v9OlM//Umd//zIwMP8LCwr/HBka/0M+P/6CfoCPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC4tbUAfXt6JVlVVLUzNDf8WHuT/4TA5/+DxO3/gMPw/3vA8P90vO7/brjs/2i06v9gsOj/Wqvl/1ak + 4f9Xot7/danS/4GMmf9STU3+T0xN/S4rK/dGQkLpV1NT0mVhYX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACuq6oAfnx8PVVRUfEuLzD/KzlE/z1UZf9Ygp7/aqHG/3O24/9xuen/bLPl/2On + 1v9emcT/cpm6/pamtfyHh4n0W1dX4ldTU7psamqJa2hoVXdzdCp+fX0TgYCADgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBfn4YYl1dykA8O/4WExL/GBYW/yAfIP8kJir/KzxJ/zhR + Y/5MW2j6U1dd8VlZXNh2cXSseHR0e2ppaUl1dHMgcnBvC4+OjgOpp6cAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJqWlgFxbW1bVlFR9FBLS/8fHBz9JyUm9zQy + Mus9PDzLTUtLnWBcXGlwbW48dXNyF3Zycgihnp4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIaEhBBdWVq6Yl5fyWBc + XY5iYGFZcG9vLXp4dxCDgoIFtLGxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo6GjAoB/ + gVF+fX8ulZKSA7e1tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA///D///+Af//4AH//gAA//AAAP+AAAB/AAAAfwAAAD8AAAA/AAAAHwAA + AB8AAAAPgAAAD4AAAA/AAAAHwAAAB+AAAAPwAAAD8AAAAfgAAAH4AAAA/AAAAPwAAAD+AAAA/wAAAP8A + AAD/gAAA/8AAAP/AAA//wAD//+Af///h//8= + + + \ No newline at end of file diff --git a/TLO/Forms/SelectCategory.Designer.cs b/TLO/Forms/SelectCategory.Designer.cs new file mode 100644 index 0000000..7bcb9b9 --- /dev/null +++ b/TLO/Forms/SelectCategory.Designer.cs @@ -0,0 +1,89 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace TLO.Forms { + partial class SelectCategory { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + + private void InitializeComponent() + { + treeView1 = new TreeView(); + _btCancel = new Button(); + _btSelected = new Button(); + _txtFrom = new TextBox(); + SuspendLayout(); + treeView1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + treeView1.Location = new Point(12, 12); + treeView1.Name = "treeView1"; + treeView1.Size = new Size(468, 495); + treeView1.TabIndex = 0; + treeView1.DoubleClick += _btSelected_Click; + _btCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + _btCancel.Location = new Point(405, 513); + _btCancel.Name = "_btCancel"; + _btCancel.Size = new Size(75, 23); + _btCancel.TabIndex = 1; + _btCancel.Text = "Отмена"; + _btCancel.UseVisualStyleBackColor = true; + _btCancel.Click += _btCancel_Click; + _btSelected.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + _btSelected.Location = new Point(324, 513); + _btSelected.Name = "_btSelected"; + _btSelected.Size = new Size(75, 23); + _btSelected.TabIndex = 2; + _btSelected.Text = "Выбрать"; + _btSelected.UseVisualStyleBackColor = true; + _btSelected.Click += _btSelected_Click; + _txtFrom.Location = new Point(12, 513); + _txtFrom.Name = "_txtFrom"; + _txtFrom.Size = new Size(306, 20); + _txtFrom.TabIndex = 3; + _txtFrom.KeyDown += _txtFrom_KeyDown; + AutoScaleDimensions = new SizeF(6f, 13f); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(492, 548); + ControlBox = false; + Controls.Add(_txtFrom); + Controls.Add(_btSelected); + Controls.Add(_btCancel); + Controls.Add(treeView1); + FormBorderStyle = FormBorderStyle.FixedToolWindow; + Name = "SelectCategory"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Выбор категории"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private TreeView treeView1; + private Button _btCancel; + private Button _btSelected; + private TextBox _txtFrom; + } +} diff --git a/TLO/Forms/SelectCategory.cs b/TLO/Forms/SelectCategory.cs new file mode 100644 index 0000000..e23e6f7 --- /dev/null +++ b/TLO/Forms/SelectCategory.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using NLog; +using TLO.Clients; +using TLO.Info; + +namespace TLO.Forms +{ + internal partial class SelectCategory : Form + { + private static Logger _logger; + + public SelectCategory() + { + if (_logger == null) + _logger = LogManager.GetLogger("SelectCategory"); + InitializeComponent(); + SelectedCategories = new List(); + } + + public List SelectedCategory { get; private set; } + + public List SelectedCategories { get; private set; } + + public void Read() + { + try + { + ClientLocalDb.Current.CategoriesSave(RuTrackerOrg.Current.GetCategories(), true); + } + catch (Exception ex) + { + var num = (int) MessageBox.Show("Не удалось загрузить список категорий.\r\n" + ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + _logger.Error(ex.Message + "\r\n" + ex.StackTrace); + } + + var array = ClientLocalDb.Current.GetCategories().OrderBy(x => x.FullName).ToArray(); + foreach (var category3 in array.Where(x => x.CategoryID > 999999).OrderBy(x => x.FullName).ToArray()) + { + var category1 = category3; + var source1 = new List(); + var categoryArray1 = array; + foreach (var category4 in categoryArray1.Where(x => x.ParentID == category1.CategoryID) + .OrderBy(x => x.FullName).ToArray()) + { + var category2 = category4; + var source2 = new List(); + var categoryArray2 = array; + foreach (var category5 in categoryArray2.Where(x => x.ParentID == category2.CategoryID) + .OrderBy(x => x.FullName).ToArray()) + source2.Add(new TreeNode(category5.Name) + { + Tag = category5 + }); + if (source2.Count() != 0) + source1.Add(new TreeNode(category2.Name, source2.ToArray()) + { + Tag = category2 + }); + else + source1.Add(new TreeNode(category2.Name) + { + Tag = category2 + }); + } + + if (source1.Count() != 0) + treeView1.Nodes.Add(new TreeNode(category1.Name, source1.ToArray()) + { + Tag = category1 + }); + else + treeView1.Nodes.Add(new TreeNode(category1.Name) + { + Tag = category1 + }); + } + } + + private void _btCancel_Click(object sender, EventArgs e) + { + SelectedCategory = null; + DialogResult = DialogResult.Cancel; + Close(); + } + + private void _btSelected_Click(object sender, EventArgs e) + { + try + { + if (treeView1 == null) + return; + var selectedNode = treeView1.SelectedNode; + if (selectedNode == null) + return; + var tag = selectedNode.Tag as Category; + if (tag == null || tag.CategoryID > 999999) + { + var num = (int) MessageBox.Show( + "Не выбран раздел или выбран корневой раздел\r\n(Корневой раздел нельзя выбирать)"); + } + else + { + SelectedCategory = new List(); + SelectedCategory.Add(tag); + foreach (var node in selectedNode.GetAllNodes()) + { + tag = node.Tag as Category; + if (!(tag == null || tag.CategoryID > 999999)) + { + SelectedCategory.Add((Category) node.Tag); + } + } + DialogResult = DialogResult.OK; + Close(); + } + } + catch (Exception ex) + { + var num = (int) MessageBox.Show("Непредвиденное исключение\r\n " + ex.Message); + throw ex; + } + } + + private void _txtFrom_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode != Keys.Return) + return; + if (string.IsNullOrWhiteSpace(_txtFrom.Text)) + return; + try + { + if (_txtFrom.Text.Split('=').Length != 2) + return; + var categoriesFromPost = + new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass).GetCategoriesFromPost( + _txtFrom.Text); + SelectedCategories = ClientLocalDb.Current.GetCategories() + .Join(categoriesFromPost, c => c.CategoryID, t => t.Item1, (c, t) => c).ToList(); + var result = new List>(); + foreach (var tuple in categoriesFromPost) + result.Add(new Tuple(tuple.Item1, 0, tuple.Item2)); + ClientLocalDb.Current.SaveSettingsReport(result); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + var num = (int) MessageBox.Show(ex.Message); + _logger.Error(ex.Message); + _logger.Debug(ex.StackTrace); + } + } + } +} \ No newline at end of file diff --git a/Forms/SelectCategory.resx b/TLO/Forms/SelectCategory.resx similarity index 100% rename from Forms/SelectCategory.resx rename to TLO/Forms/SelectCategory.resx diff --git a/Forms/SettingsForm.cs b/TLO/Forms/SettingsForm.Designer.cs similarity index 52% rename from Forms/SettingsForm.cs rename to TLO/Forms/SettingsForm.Designer.cs index 86e226e..50a7b9d 100644 --- a/Forms/SettingsForm.cs +++ b/TLO/Forms/SettingsForm.Designer.cs @@ -1,680 +1,41 @@ -// Decompiled with JetBrains decompiler -// Type: TLO.local.SettingsForm -// Assembly: TLO.local, Version=2.6.5944.27906, Culture=neutral, PublicKeyToken=null -// MVID: E76CFDB0-1920-4151-9DD8-5FF51DE7CC23 -// Assembly location: C:\Users\root\Downloads\TLO_2.6.2.21\TLO.local.exe - + using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Drawing; -using System.Linq; using System.Windows.Forms; -namespace TLO.local -{ - public class SettingsForm : Form - { - private BindingSource _TorrentClientsSource = new BindingSource(); - private BindingSource _CategoriesSource = new BindingSource(); - private IContainer components; - private Button _btCheck; - private Button _btCancel; - private Button _btSave; - private TabPage _tpCategories; - private Panel panel1; - private GroupBox groupBox7; - private ComboBox _cbSubFolder; - private Label label22; - private Button _CategoriesBtSelectFolder; - private Label label18; - private TextBox _CategoriesTbFolderDownloads; - private Label label16; - private ComboBox _CategoriesCbStartCountSeeders; - private Label label15; - private GroupBox groupBox6; - private TextBox _CategoriesTbFullName; - private Label label14; - private TextBox _CategoriesTbCategoryID; - private Label label13; - private Button _btCategoryRemove; - private Button _btCategoryAdd; - private DataGridView dgwCategories; - private DataGridViewTextBoxColumn ColumnCategoryCategoryID; - private DataGridViewTextBoxColumn ColumnCategoryName; - private TabPage tbpTorrentClients; - private GroupBox groupBox5; - private Button _btTorrentClientAdd; - private Button _btTorrentClientDelete; - private GroupBox groupBox3; - private TextBox _tbTorrentClientHostIP; - private Label label7; - private Label label6; - private TextBox _tbTorrentClientUserPassword; - private TextBox _tbTorrentClientUserName; - private TextBox _tbTorrentClientPort; - private Label label5; - private DataGridView dgwTorrentClients; - private DataGridViewTextBoxColumn UID; - private DataGridViewTextBoxColumn FolderName; - private ComboBox _cbTorrentClientType; - private Label label2; - private Label label1; - private TextBox _tbTorrentClientName; - private TabControl tabControl1; - private ComboBox _CategoriesCbTorrentClient; - private Label label3; - private CheckBox _cbIsSaveTorrentFile; - private CheckBox _cbIsSaveWebPage; - private TabPage tabPage1; - private ForumPages forumPages1; - private TabPage tabPage2; - private GroupBox groupBox1; - private Label label8; - private TextBox _appKeeperPass; - private TextBox _appKeeperName; - private Label label4; - private GroupBox groupBox2; - private CheckBox _appIsAvgCountSeeders; - private Label label10; - private GroupBox groupBox4; - private NumericUpDown _appPeriodRunAndStopTorrents; - private Label label11; - private Label label12; - private CheckBox _appIsUpdateStatistics; - private NumericUpDown _appCountDaysKeepHistory; - private Label label19; - private NumericUpDown _appCountSeedersReport; - private Label label20; - private CheckBox _appSelectLessOrEqual; - private NumericUpDown _appLogLevel; - private Label label21; - private Label label23; - private RadioButton _tcrbRemote; - private RadioButton _tcrbCurrent; - private CheckBox _appIsNotSaveStatistics; - private GroupBox groupBox8; - private Label label9; - private Label label27; - private Label label26; - private Label label25; - private Label label24; - private TextBox _appReportLine; - private Label label17; - private Label label29; - private Label label28; - private Label label32; - private TextBox _appReportBottom; - private Label label31; - private Label label30; - private TextBox _appReportTop2; - private TextBox _appReportTop1; - private Label label33; - private Label label34; - private Label label35; - private Label label36; - private Label label38; - private Label label37; - private Label label39; - private TextBox _CategoriesTbLabel; - private Label label40; - private TabPage _tpAllCategories; - private CheckBox _dbLoadInMemoryCheckbox; - private Panel panel2; - - public SettingsForm() - { - this.InitializeComponent(); - this._tbTorrentClientName.Enabled = false; - this._cbTorrentClientType.Enabled = false; - this._tbTorrentClientHostIP.Enabled = false; - this._tbTorrentClientPort.Enabled = false; - this._tbTorrentClientUserName.Enabled = false; - this._tbTorrentClientUserPassword.Enabled = false; - this.dgwTorrentClients.AutoGenerateColumns = false; - this.dgwTorrentClients.ClearSelection(); - this.dgwTorrentClients.DataSource = (object) null; - this._TorrentClientsSource = new BindingSource(); - this._TorrentClientsSource.DataSource = (object) ClientLocalDB.Current.GetTorrentClients(); - this.dgwTorrentClients.DataSource = (object) this._TorrentClientsSource; - this.dgwCategories.AutoGenerateColumns = false; - this.dgwCategories.ClearSelection(); - this.dgwCategories.DataSource = (object) null; - this._CategoriesSource = new BindingSource(); - this._CategoriesSource.DataSource = (object) ClientLocalDB.Current.GetCategoriesEnable(); - this.dgwCategories.DataSource = (object) this._CategoriesSource; - if (this._CategoriesSource.Count > 0) - this._CategoriesSource.Position = 0; - if (this._TorrentClientsSource.Count > 0) - this._TorrentClientsSource.Position = 0; - this.forumPages1.LoadSettings(); - CreatePageAllCategories(); - Settings current = Settings.Current; - this._appKeeperName.Text = current.KeeperName; - this._appKeeperPass.Text = current.KeeperPass; - this._appIsUpdateStatistics.Checked = current.IsUpdateStatistics; - this._appCountDaysKeepHistory.Value = (Decimal) current.CountDaysKeepHistory; - this._appPeriodRunAndStopTorrents.Value = (Decimal) current.PeriodRunAndStopTorrents; - this._appCountSeedersReport.Value = (Decimal) current.CountSeedersReport; - this._appIsAvgCountSeeders.Checked = current.IsAvgCountSeeders; - this._appSelectLessOrEqual.Checked = current.IsSelectLessOrEqual; - { - CheckState checkState; - if (Settings.Current.LoadDBInMemory == null) - { - checkState = CheckState.Indeterminate; - } - else if ((bool)current.LoadDBInMemory) - { - checkState = CheckState.Checked; - } - else - { - checkState = CheckState.Unchecked; - } - - this._dbLoadInMemoryCheckbox.AutoSize = true; - this._dbLoadInMemoryCheckbox.Checked = current.LoadDBInMemory.GetValueOrDefault(false); - this._dbLoadInMemoryCheckbox.CheckState = checkState; - } - NumericUpDown appLogLevel = this._appLogLevel; - int? logLevel = current.LogLevel; - int num1; - if (!logLevel.HasValue) - { - num1 = 0; - } - else - { - logLevel = current.LogLevel; - num1 = logLevel.Value; - } - - Decimal num2 = (Decimal) num1; - appLogLevel.Value = num2; - this._appIsNotSaveStatistics.Checked = current.IsNotSaveStatistics; - this._appReportTop1.Text = current.ReportTop1; - this._appReportTop2.Text = current.ReportTop2; - this._appReportLine.Text = current.ReportLine; - this._appReportBottom.Text = current.ReportBottom; - } - - private void _Focus_Enter(object sender, EventArgs e) - { - if (this._TorrentClientsSource.Current != null) - { - TorrentClientInfo current = this._TorrentClientsSource.Current as TorrentClientInfo; - if (sender == this._tbTorrentClientName) - current.Name = this._tbTorrentClientName.Text; - else if (sender == this._cbTorrentClientType) - current.Type = this._cbTorrentClientType.Text; - else if (sender == this._tbTorrentClientHostIP) - current.ServerName = this._tbTorrentClientHostIP.Text; - else if (sender == this._tbTorrentClientPort) - { - int result = 0; - if (int.TryParse(this._tbTorrentClientPort.Text, out result)) - current.ServerPort = result; - else - this._tbTorrentClientPort.Text = "0"; - } - else if (sender == this._tbTorrentClientUserName) - current.UserName = this._tbTorrentClientUserName.Text; - else if (sender == this._tbTorrentClientUserPassword) - current.UserPassword = this._tbTorrentClientUserPassword.Text; - else if (sender == this._tcrbCurrent && this._tcrbCurrent.Checked) - { - current.ServerName = "127.0.0.1"; - this._tbTorrentClientHostIP.Enabled = false; - } - else if (sender == this._tcrbRemote && this._tcrbRemote.Checked) - { - current.ServerName = this._tbTorrentClientHostIP.Text; - this._tbTorrentClientHostIP.Enabled = true; - } - } - - if (this._CategoriesSource.Current == null) - return; - Category current1 = this._CategoriesSource.Current as Category; - if (sender == this._CategoriesCbTorrentClient) - { - TorrentClientInfo selectedItem = this._CategoriesCbTorrentClient.SelectedItem as TorrentClientInfo; - if (selectedItem == null) - return; - current1.TorrentClientUID = selectedItem.UID; - } - else if (sender == this._CategoriesCbStartCountSeeders) - { - int result = 0; - if (!int.TryParse(this._CategoriesCbStartCountSeeders.SelectedItem as string, out result)) - return; - current1.CountSeeders = result; - } - else if (sender == this._CategoriesTbFolderDownloads) - current1.Folder = this._CategoriesTbFolderDownloads.Text; - else if (sender == this._cbIsSaveTorrentFile) - current1.IsSaveTorrentFiles = this._cbIsSaveTorrentFile.Checked; - else if (sender == this._cbIsSaveWebPage) - current1.IsSaveWebPage = this._cbIsSaveWebPage.Checked; - else if (sender == this._cbSubFolder) - { - string selectedItem = this._cbSubFolder.SelectedItem as string; - if (string.IsNullOrWhiteSpace(selectedItem)) - return; - if (!(selectedItem == "Не нужен")) - { - if (!(selectedItem == "С ID топика")) - { - if (!(selectedItem == "Запрашивать")) - return; - current1.CreateSubFolder = 2; - } - else - current1.CreateSubFolder = 1; - } - else - current1.CreateSubFolder = 0; - } - else - { - if (sender != this._CategoriesTbLabel) - return; - current1.Label = string.IsNullOrWhiteSpace(this._CategoriesTbLabel.Text) - ? current1.FullName - : this._CategoriesTbLabel.Text.Trim(); - } - } - - private void SelectionChanged(object sender, EventArgs e) - { - if (sender == this.dgwTorrentClients) - { - if (this._TorrentClientsSource.Current == null) - { - this._tbTorrentClientName.Enabled = false; - this._cbTorrentClientType.Enabled = false; - this._tbTorrentClientHostIP.Enabled = false; - this._tbTorrentClientPort.Enabled = false; - this._tbTorrentClientUserName.Enabled = false; - this._tbTorrentClientUserPassword.Enabled = false; - this._tbTorrentClientName.Text = string.Empty; - this._cbTorrentClientType.Text = string.Empty; - this._tbTorrentClientHostIP.Text = string.Empty; - this._tbTorrentClientPort.Text = string.Empty; - this._tbTorrentClientUserName.Text = string.Empty; - this._tbTorrentClientUserPassword.Text = string.Empty; - this._tcrbRemote.Checked = false; - this._tcrbCurrent.Checked = true; - this._tbTorrentClientHostIP.Enabled = false; - } - else - { - TorrentClientInfo current = this._TorrentClientsSource.Current as TorrentClientInfo; - this._tbTorrentClientName.Enabled = true; - this._cbTorrentClientType.Enabled = true; - this._tbTorrentClientHostIP.Enabled = true; - this._tbTorrentClientPort.Enabled = true; - this._tbTorrentClientUserName.Enabled = true; - this._tbTorrentClientUserPassword.Enabled = true; - this._tbTorrentClientName.Text = current.Name; - this._cbTorrentClientType.Text = current.Type; - if (current.ServerName == "127.0.0.1") - { - this._tcrbRemote.Checked = false; - this._tcrbCurrent.Checked = true; - } - else - { - this._tbTorrentClientHostIP.Text = current.ServerName; - this._tcrbCurrent.Checked = false; - this._tcrbRemote.Checked = true; - } - - this._tbTorrentClientPort.Text = current.ServerPort.ToString(); - this._tbTorrentClientUserName.Text = current.UserName; - this._tbTorrentClientUserPassword.Text = current.UserPassword; - } - } - - if (sender == this.dgwCategories) - { - if (this._CategoriesSource.Current == null) - { - this._CategoriesTbCategoryID.Text = string.Empty; - this._CategoriesTbFullName.Text = string.Empty; - this._CategoriesCbStartCountSeeders.Enabled = false; - this._CategoriesTbLabel.Text = string.Empty; - } - else - { - Category obj = this._CategoriesSource.Current as Category; - this._CategoriesTbCategoryID.Text = obj.CategoryID.ToString(); - this._CategoriesTbFullName.Text = obj.FullName; - this._CategoriesCbStartCountSeeders.Enabled = true; - ComboBox startCountSeeders = this._CategoriesCbStartCountSeeders; - int num; - string str; - if (obj.CountSeeders < 0) - { - str = "-"; - } - else - { - num = obj.CountSeeders; - str = num.ToString(); - } - - startCountSeeders.SelectedItem = (object) str; - this._CategoriesTbFolderDownloads.Text = obj.Folder; - this._CategoriesCbTorrentClient.DataSource = (object) null; - this._CategoriesCbTorrentClient.DataSource = this._TorrentClientsSource.DataSource; - this._CategoriesCbTorrentClient.SelectedItem = - (object) (this._CategoriesCbTorrentClient.DataSource as List) - .Where((Func) (x => x.UID == obj.TorrentClientUID)) - .FirstOrDefault(); - num = obj.CreateSubFolder; - switch (num) - { - case 0: - this._cbSubFolder.SelectedItem = (object) "Не нужен"; - break; - case 1: - this._cbSubFolder.SelectedItem = (object) "С ID топика"; - break; - case 2: - this._cbSubFolder.SelectedItem = (object) "Запрашивать"; - break; - } - - this._cbIsSaveWebPage.Checked = obj.IsSaveWebPage; - this._cbIsSaveTorrentFile.Checked = obj.IsSaveTorrentFiles; - this._CategoriesTbLabel.Text = string.IsNullOrWhiteSpace(obj.Label) ? obj.FullName : obj.Label; - } - } - - if (sender != this._appIsNotSaveStatistics) - return; - if (this._appIsNotSaveStatistics.Checked) - { - this._appIsUpdateStatistics.Checked = false; - this._appIsUpdateStatistics.Enabled = false; - } - else - this._appIsUpdateStatistics.Enabled = true; - } - - private bool hasChanges = false; - - private void ClickButtons(object sender, EventArgs e) - { - Cursor.Current = Cursors.WaitCursor; - try - { - if (sender == this._btTorrentClientAdd) - { - this._TorrentClientsSource.Add((object) new TorrentClientInfo()); - this._TorrentClientsSource.Position = this._TorrentClientsSource.Count; - } - else if (sender == this._btTorrentClientDelete) - { - if (this._TorrentClientsSource.Current == null) - return; - TorrentClientInfo current = this._TorrentClientsSource.Current as TorrentClientInfo; - if (MessageBox.Show("Вы хотите удалить из списка torrent-клиент \"" + current.Name + "\"?", - "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == - DialogResult.Yes) - this._TorrentClientsSource.Remove((object) current); - } - } - catch - { - } - - if (sender == this._dbLoadInMemoryCheckbox) - { - hasChanges = true; - } - - try - { - if (sender == this._btCategoryAdd) - { - SelectCategory dialog = new SelectCategory(); - dialog.Read(); - if (dialog.ShowDialog() == DialogResult.OK) - { - if (dialog.SelectedCategories.Count() > 0) - { - dialog.SelectedCategories.ForEach((Action) (x => - { - x.IsEnable = true; - this._CategoriesSource.Add((object) x); - })); - this._CategoriesSource.Position = this._CategoriesSource.Count; - } - - if (dialog.SelectedCategory == null) - return; - if ((this._CategoriesSource.DataSource as List).Any( - (Func) (x => x.CategoryID == dialog.SelectedCategory.CategoryID))) - { - int num = (int) MessageBox.Show("Выбранная категория уже присутствует"); - } - else - { - dialog.SelectedCategory.IsEnable = true; - this._CategoriesSource.Add((object) dialog.SelectedCategory); - this._CategoriesSource.Position = this._CategoriesSource.Count; - } - } - } - else if (sender == this._btCategoryRemove) - { - if (this._CategoriesSource.Current == null) - return; - Category current = this._CategoriesSource.Current as Category; - if (MessageBox.Show("Удалить из обработки раздел \"" + current.Name + "\"?", "Подтверждение", - MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes) - this._CategoriesSource.Remove((object) current); - } - else if (sender == this._CategoriesBtSelectFolder) - { - if (this._CategoriesSource.Current == null) - return; - Category current = this._CategoriesSource.Current as Category; - FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); - folderBrowserDialog.SelectedPath = - string.IsNullOrWhiteSpace(current.Folder) ? "c:\\" : current.Folder; - if (folderBrowserDialog.ShowDialog() == DialogResult.OK) - { - current.Folder = folderBrowserDialog.SelectedPath; - this._CategoriesTbFolderDownloads.Text = current.Folder; - } - } - } - catch - { - } - - try - { - if (sender == this._btSave) - { - ClientLocalDB.Current.SaveTorrentClients( - (IEnumerable) - (this._TorrentClientsSource.DataSource as List), true); - ClientLocalDB.Current.CategoriesSave( - (IEnumerable) (this._CategoriesSource.DataSource as List), false); - this.forumPages1.Save(); - this.DialogResult = DialogResult.OK; - Settings current = Settings.Current; - current.KeeperName = this._appKeeperName.Text; - current.KeeperPass = this._appKeeperPass.Text; - current.IsUpdateStatistics = this._appIsUpdateStatistics.Checked; - current.CountDaysKeepHistory = (int) this._appCountDaysKeepHistory.Value; - current.PeriodRunAndStopTorrents = (int) this._appPeriodRunAndStopTorrents.Value; - current.CountSeedersReport = (int) this._appCountSeedersReport.Value; - current.IsAvgCountSeeders = this._appIsAvgCountSeeders.Checked; - current.IsSelectLessOrEqual = this._appSelectLessOrEqual.Checked; - current.LogLevel = new int?((int) this._appLogLevel.Value); - current.IsNotSaveStatistics = this._appIsNotSaveStatistics.Checked; - current.ReportTop1 = this._appReportTop1.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); - current.ReportTop2 = this._appReportTop2.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); - current.ReportLine = this._appReportLine.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); - current.ReportBottom = this._appReportBottom.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); - if (this._dbLoadInMemoryCheckbox.CheckState != CheckState.Indeterminate) - { - current.LoadDBInMemory = this._dbLoadInMemoryCheckbox.Checked; - } - current.Save(); - ClientLocalDB.Current.SaveToDatabase(); - this.Close(); - if (hasChanges) - { - MessageBox.Show("Для вступления изменений в силу может потребоваться перезапустить программу.", - "Внимание"); - } - } - else if (sender == this._btCancel) - { - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - else - { - if (this._btCheck != sender) - return; - List stringList = new List(); - foreach (TorrentClientInfo torrentClientInfo in - this._TorrentClientsSource.DataSource as List) - { - try - { - ITorrentClient torrentClient = torrentClientInfo.Create(); - if (torrentClient == null) - stringList.Add(string.Format( - "Торрент-клиент \"{0}\": Не удалось определить тип torrent-клиента", - (object) torrentClientInfo.Name)); - else - torrentClient.Ping(); - } - catch - { - stringList.Add(string.Format("Не удалось подключиться к торрент-клиенту \"{0}\"", - (object) torrentClientInfo.Name)); - } - } - - foreach (string text in stringList) - { - int num = (int) MessageBox.Show(text, "Проверка"); - } - - int num1 = (int) MessageBox.Show("Подключение к torrent-клиентам проверено.", "Проверка"); - } - } - catch (Exception ex) - { - Cursor.Current = Cursors.Default; - int num = (int) MessageBox.Show(ex.Message); - } - } +namespace TLO.Forms { + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + partial class SettingsForm { + + /// + /// Required designer variable. + /// + private IContainer components = null; - private void CreatePageAllCategories() + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { - Control control = this.panel2; - Dictionary dictionary1 = ClientLocalDB.Current.GetCategories() - .ToDictionary((Func) (x => x.CategoryID), - (Func) (x => x)); - Dictionary categoriesEnable = ClientLocalDB.Current.GetCategoriesEnable() - .ToDictionary((Func) (x => x.CategoryID), - (Func) (x => x)); - categoriesEnable.ToDictionary, int, int>( - (Func, int>) (x => x.Key), - (Func, int>) (x => x.Value.ParentID)); - for (int index = 0; index < 3; ++index) - { - foreach (Category category in categoriesEnable.Values.ToArray()) - { - if (!categoriesEnable.ContainsKey(category.ParentID) && dictionary1.ContainsKey(category.ParentID)) - categoriesEnable.Add(dictionary1[category.ParentID].CategoryID, dictionary1[category.ParentID]); - } - } - - for (int index = 0; index < 3; ++index) + if (disposing && (components != null)) { - List list = dictionary1.Values.ToList(); - foreach (Category category1 in categoriesEnable.Values.ToList()) - { - Category c = category1; - foreach (Category category2 in list.Where((Func) (x => - { - if (!categoriesEnable.ContainsKey(x.CategoryID)) - return x.ParentID == c.CategoryID; - return false; - })).ToArray()) - { - if (!categoriesEnable.ContainsKey(category2.CategoryID) && - dictionary1.ContainsKey(category2.CategoryID)) - categoriesEnable.Add(category2.CategoryID, category2); - } - } + components.Dispose(); } - - Dictionary dictionary2 = ClientLocalDB.Current.GetReports(new int?()) - .Where, Tuple>>( - (Func, Tuple>, bool>) (x => - { - if (x.Key.Item2 == 0) - return (uint) x.Key.Item1 > 0U; - return false; - })).ToDictionary, Tuple>, int, string>( - (Func, Tuple>, int>) (x => x.Key.Item1), - (Func, Tuple>, string>) (x => x.Value.Item1)); - int num = 0; - int y1 = 10; - foreach (Category category in (IEnumerable) categoriesEnable.Values.OrderBy( - (Func) (x => x.FullName))) - { - Label label1 = new Label(); - label1.AutoSize = true; - label1.Location = new Point(3, y1); - label1.Size = new Size(35, 13); - label1.TabIndex = num; - label1.Text = category.FullName; - control.Controls.Add((Control) label1); - int y2 = y1 + 16; - Label label2 = new Label(); - label2.Location = new Point(6, y2); - label2.Size = new Size(123, 20); - label2.Text = "Списки хранимого"; - control.Controls.Add((Control) label2); - ++num; - TextBox textBox = new TextBox(); - textBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - textBox.Location = new Point(135, y2); - textBox.Size = new Size(this.panel1.Size.Width - 135, 20); - textBox.TabIndex = num; - textBox.Text = - !string.IsNullOrWhiteSpace(category.ReportList) || !dictionary2.ContainsKey(category.CategoryID) - ? category.ReportList - : dictionary2[category.CategoryID]; - control.Controls.Add((Control) textBox); - y1 = y2 + 26; - } - } - - protected override void Dispose(bool disposing) - { - if (disposing && this.components != null) - this.components.Dispose(); base.Dispose(disposing); } + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// private void InitializeComponent() { - this._btCheck = new System.Windows.Forms.Button(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsForm)); this._btCancel = new System.Windows.Forms.Button(); this._btSave = new System.Windows.Forms.Button(); this._tpCategories = new System.Windows.Forms.TabPage(); @@ -708,73 +69,95 @@ private void InitializeComponent() this.groupBox5 = new System.Windows.Forms.GroupBox(); this._btTorrentClientAdd = new System.Windows.Forms.Button(); this._btTorrentClientDelete = new System.Windows.Forms.Button(); - this.groupBox3 = new System.Windows.Forms.GroupBox(); - this._tcrbRemote = new System.Windows.Forms.RadioButton(); - this._tcrbCurrent = new System.Windows.Forms.RadioButton(); - this._tbTorrentClientHostIP = new System.Windows.Forms.TextBox(); - this.label7 = new System.Windows.Forms.Label(); - this.label6 = new System.Windows.Forms.Label(); - this._tbTorrentClientUserPassword = new System.Windows.Forms.TextBox(); - this._tbTorrentClientUserName = new System.Windows.Forms.TextBox(); - this._tbTorrentClientPort = new System.Windows.Forms.TextBox(); - this.label5 = new System.Windows.Forms.Label(); this.dgwTorrentClients = new System.Windows.Forms.DataGridView(); this.UID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientType = new System.Windows.Forms.DataGridViewComboBoxColumn(); this.FolderName = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this._cbTorrentClientType = new System.Windows.Forms.ComboBox(); - this.label2 = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this._tbTorrentClientName = new System.Windows.Forms.TextBox(); + this.TorrentClientHost = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientPort = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientUsername = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientPassword = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.TorrentClientRemove = new System.Windows.Forms.DataGridViewButtonColumn(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPage2 = new System.Windows.Forms.TabPage(); + this.groupBox10 = new System.Windows.Forms.GroupBox(); + this.label47 = new System.Windows.Forms.Label(); + this.showNotificationInTray = new System.Windows.Forms.CheckBox(); + this.showTrayIcon = new System.Windows.Forms.CheckBox(); + this.closeToTray = new System.Windows.Forms.CheckBox(); + this.hideToTray = new System.Windows.Forms.CheckBox(); + this.groupBox9 = new System.Windows.Forms.GroupBox(); + this.rutrackerHost = new System.Windows.Forms.TextBox(); + this.label48 = new System.Windows.Forms.Label(); + this.connectionCheck = new System.Windows.Forms.Label(); + this.SystemProxy = new System.Windows.Forms.CheckBox(); + this.ProxyAddButton = new System.Windows.Forms.Button(); + this.ProxyListBox = new System.Windows.Forms.ListBox(); + this.DisableCertVerifyCheck = new System.Windows.Forms.CheckBox(); + this.useProxyCheckBox = new System.Windows.Forms.CheckBox(); + this.label41 = new System.Windows.Forms.Label(); + this.apiHosts = new System.Windows.Forms.ComboBox(); + this.proxyInput = new System.Windows.Forms.TextBox(); + this.label42 = new System.Windows.Forms.Label(); this.groupBox8 = new System.Windows.Forms.GroupBox(); - this.label39 = new System.Windows.Forms.Label(); - this.label38 = new System.Windows.Forms.Label(); - this.label37 = new System.Windows.Forms.Label(); - this.label36 = new System.Windows.Forms.Label(); - this.label35 = new System.Windows.Forms.Label(); - this.label34 = new System.Windows.Forms.Label(); - this.label33 = new System.Windows.Forms.Label(); - this.label32 = new System.Windows.Forms.Label(); - this._appReportBottom = new System.Windows.Forms.TextBox(); - this.label31 = new System.Windows.Forms.Label(); - this.label30 = new System.Windows.Forms.Label(); - this._appReportTop2 = new System.Windows.Forms.TextBox(); - this._appReportTop1 = new System.Windows.Forms.TextBox(); - this.label29 = new System.Windows.Forms.Label(); - this.label28 = new System.Windows.Forms.Label(); - this.label27 = new System.Windows.Forms.Label(); - this.label26 = new System.Windows.Forms.Label(); - this.label25 = new System.Windows.Forms.Label(); - this.label24 = new System.Windows.Forms.Label(); - this._appReportLine = new System.Windows.Forms.TextBox(); - this.label17 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this._appCountSeedersReport = new System.Windows.Forms.NumericUpDown(); this.label19 = new System.Windows.Forms.Label(); this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.closeProgramCopies = new System.Windows.Forms.CheckBox(); + this._appCountDaysKeepHistory = new System.Windows.Forms.NumericUpDown(); + this.label46 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); this._dbLoadInMemoryCheckbox = new System.Windows.Forms.CheckBox(); this._appIsNotSaveStatistics = new System.Windows.Forms.CheckBox(); this.label23 = new System.Windows.Forms.Label(); this._appLogLevel = new System.Windows.Forms.NumericUpDown(); this.label21 = new System.Windows.Forms.Label(); - this.label20 = new System.Windows.Forms.Label(); - this._appSelectLessOrEqual = new System.Windows.Forms.CheckBox(); this.label12 = new System.Windows.Forms.Label(); this._appIsUpdateStatistics = new System.Windows.Forms.CheckBox(); this._appPeriodRunAndStopTorrents = new System.Windows.Forms.NumericUpDown(); this.label11 = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); - this._appCountDaysKeepHistory = new System.Windows.Forms.NumericUpDown(); - this.label10 = new System.Windows.Forms.Label(); this._appIsAvgCountSeeders = new System.Windows.Forms.CheckBox(); + this.label20 = new System.Windows.Forms.Label(); + this._appSelectLessOrEqual = new System.Windows.Forms.CheckBox(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.label8 = new System.Windows.Forms.Label(); this._appKeeperPass = new System.Windows.Forms.TextBox(); this._appKeeperName = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); + this.templatesTabPage3 = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.label17 = new System.Windows.Forms.Label(); + this.categoryReportTemplate = new System.Windows.Forms.TextBox(); + this.reportHeaderTemplate = new System.Windows.Forms.TextBox(); + this.label44 = new System.Windows.Forms.Label(); + this._appReportLine = new System.Windows.Forms.TextBox(); + this.summaryReportTemplate = new System.Windows.Forms.TextBox(); + this.label45 = new System.Windows.Forms.Label(); + this.label43 = new System.Windows.Forms.Label(); + this.label30 = new System.Windows.Forms.Label(); + this.label31 = new System.Windows.Forms.Label(); + this._appReportTop1 = new System.Windows.Forms.TextBox(); + this._appReportTop2 = new System.Windows.Forms.TextBox(); + this.label32 = new System.Windows.Forms.Label(); + this._appReportBottom = new System.Windows.Forms.TextBox(); + this.label39 = new System.Windows.Forms.Label(); + this.label38 = new System.Windows.Forms.Label(); + this.label37 = new System.Windows.Forms.Label(); + this.label36 = new System.Windows.Forms.Label(); + this.label35 = new System.Windows.Forms.Label(); + this.label34 = new System.Windows.Forms.Label(); + this.label33 = new System.Windows.Forms.Label(); + this.label29 = new System.Windows.Forms.Label(); + this.label28 = new System.Windows.Forms.Label(); + this.label27 = new System.Windows.Forms.Label(); + this.label26 = new System.Windows.Forms.Label(); + this.label25 = new System.Windows.Forms.Label(); + this.label24 = new System.Windows.Forms.Label(); this.tabPage1 = new System.Windows.Forms.TabPage(); - this.forumPages1 = new TLO.local.ForumPages(); + this.forumPages1 = new TLO.Forms.ForumPages(); this._tpAllCategories = new System.Windows.Forms.TabPage(); this.panel2 = new System.Windows.Forms.Panel(); this._tpCategories.SuspendLayout(); @@ -784,37 +167,29 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.dgwCategories)).BeginInit(); this.tbpTorrentClients.SuspendLayout(); this.groupBox5.SuspendLayout(); - this.groupBox3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dgwTorrentClients)).BeginInit(); this.tabControl1.SuspendLayout(); this.tabPage2.SuspendLayout(); + this.groupBox10.SuspendLayout(); + this.groupBox9.SuspendLayout(); this.groupBox8.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._appCountSeedersReport)).BeginInit(); this.groupBox4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._appCountDaysKeepHistory)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this._appLogLevel)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this._appPeriodRunAndStopTorrents)).BeginInit(); this.groupBox2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this._appCountDaysKeepHistory)).BeginInit(); this.groupBox1.SuspendLayout(); + this.templatesTabPage3.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); this.tabPage1.SuspendLayout(); this._tpAllCategories.SuspendLayout(); this.SuspendLayout(); // - // _btCheck - // - this._btCheck.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._btCheck.Location = new System.Drawing.Point(12, 623); - this._btCheck.Name = "_btCheck"; - this._btCheck.Size = new System.Drawing.Size(75, 23); - this._btCheck.TabIndex = 16; - this._btCheck.Text = "Проверить"; - this._btCheck.UseVisualStyleBackColor = true; - this._btCheck.Click += new System.EventHandler(this.ClickButtons); - // // _btCancel // this._btCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._btCancel.Location = new System.Drawing.Point(970, 623); + this._btCancel.Location = new System.Drawing.Point(901, 619); this._btCancel.Name = "_btCancel"; this._btCancel.Size = new System.Drawing.Size(75, 23); this._btCancel.TabIndex = 15; @@ -825,7 +200,7 @@ private void InitializeComponent() // _btSave // this._btSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._btSave.Location = new System.Drawing.Point(889, 623); + this._btSave.Location = new System.Drawing.Point(820, 619); this._btSave.Name = "_btSave"; this._btSave.Size = new System.Drawing.Size(75, 23); this._btSave.TabIndex = 14; @@ -842,7 +217,7 @@ private void InitializeComponent() this._tpCategories.Location = new System.Drawing.Point(4, 22); this._tpCategories.Name = "_tpCategories"; this._tpCategories.Padding = new System.Windows.Forms.Padding(3); - this._tpCategories.Size = new System.Drawing.Size(1041, 591); + this._tpCategories.Size = new System.Drawing.Size(975, 591); this._tpCategories.TabIndex = 4; this._tpCategories.Text = "Разделы/Подразделы"; this._tpCategories.UseVisualStyleBackColor = true; @@ -857,7 +232,7 @@ private void InitializeComponent() this.panel1.Controls.Add(this.groupBox6); this.panel1.Location = new System.Drawing.Point(254, 35); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(787, 550); + this.panel1.Size = new System.Drawing.Size(721, 550); this.panel1.TabIndex = 6; // // groupBox7 @@ -880,7 +255,7 @@ private void InitializeComponent() this.groupBox7.Controls.Add(this.label15); this.groupBox7.Location = new System.Drawing.Point(3, 122); this.groupBox7.Name = "groupBox7"; - this.groupBox7.Size = new System.Drawing.Size(778, 235); + this.groupBox7.Size = new System.Drawing.Size(712, 235); this.groupBox7.TabIndex = 6; this.groupBox7.TabStop = false; // @@ -890,7 +265,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this._CategoriesTbLabel.Location = new System.Drawing.Point(115, 202); this._CategoriesTbLabel.Name = "_CategoriesTbLabel"; - this._CategoriesTbLabel.Size = new System.Drawing.Size(657, 20); + this._CategoriesTbLabel.Size = new System.Drawing.Size(591, 20); this._CategoriesTbLabel.TabIndex = 15; this._CategoriesTbLabel.Enter += new System.EventHandler(this._Focus_Enter); this._CategoriesTbLabel.Leave += new System.EventHandler(this._Focus_Enter); @@ -951,7 +326,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this._CategoriesTbFolderDownloads.Location = new System.Drawing.Point(9, 103); this._CategoriesTbFolderDownloads.Name = "_CategoriesTbFolderDownloads"; - this._CategoriesTbFolderDownloads.Size = new System.Drawing.Size(733, 20); + this._CategoriesTbFolderDownloads.Size = new System.Drawing.Size(667, 20); this._CategoriesTbFolderDownloads.TabIndex = 5; this._CategoriesTbFolderDownloads.Enter += new System.EventHandler(this._Focus_Enter); this._CategoriesTbFolderDownloads.Leave += new System.EventHandler(this._Focus_Enter); @@ -982,7 +357,7 @@ private void InitializeComponent() // _CategoriesBtSelectFolder // this._CategoriesBtSelectFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this._CategoriesBtSelectFolder.Location = new System.Drawing.Point(742, 102); + this._CategoriesBtSelectFolder.Location = new System.Drawing.Point(676, 102); this._CategoriesBtSelectFolder.Name = "_CategoriesBtSelectFolder"; this._CategoriesBtSelectFolder.Size = new System.Drawing.Size(30, 22); this._CategoriesBtSelectFolder.TabIndex = 7; @@ -1051,7 +426,7 @@ private void InitializeComponent() this.groupBox6.Controls.Add(this.label13); this.groupBox6.Location = new System.Drawing.Point(3, 3); this.groupBox6.Name = "groupBox6"; - this.groupBox6.Size = new System.Drawing.Size(778, 113); + this.groupBox6.Size = new System.Drawing.Size(712, 113); this.groupBox6.TabIndex = 5; this.groupBox6.TabStop = false; this.groupBox6.Text = "Данные о выбраном разделе"; @@ -1065,7 +440,7 @@ private void InitializeComponent() this._CategoriesTbFullName.Multiline = true; this._CategoriesTbFullName.Name = "_CategoriesTbFullName"; this._CategoriesTbFullName.ReadOnly = true; - this._CategoriesTbFullName.Size = new System.Drawing.Size(766, 49); + this._CategoriesTbFullName.Size = new System.Drawing.Size(700, 49); this._CategoriesTbFullName.TabIndex = 3; // // label14 @@ -1155,7 +530,7 @@ private void InitializeComponent() this.tbpTorrentClients.Location = new System.Drawing.Point(4, 22); this.tbpTorrentClients.Name = "tbpTorrentClients"; this.tbpTorrentClients.Padding = new System.Windows.Forms.Padding(3); - this.tbpTorrentClients.Size = new System.Drawing.Size(1041, 591); + this.tbpTorrentClients.Size = new System.Drawing.Size(975, 591); this.tbpTorrentClients.TabIndex = 0; this.tbpTorrentClients.Text = "Torrent-клиенты"; // @@ -1166,15 +541,10 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.groupBox5.Controls.Add(this._btTorrentClientAdd); this.groupBox5.Controls.Add(this._btTorrentClientDelete); - this.groupBox5.Controls.Add(this.groupBox3); this.groupBox5.Controls.Add(this.dgwTorrentClients); - this.groupBox5.Controls.Add(this._cbTorrentClientType); - this.groupBox5.Controls.Add(this.label2); - this.groupBox5.Controls.Add(this.label1); - this.groupBox5.Controls.Add(this._tbTorrentClientName); this.groupBox5.Location = new System.Drawing.Point(8, 6); this.groupBox5.Name = "groupBox5"; - this.groupBox5.Size = new System.Drawing.Size(1026, 360); + this.groupBox5.Size = new System.Drawing.Size(960, 583); this.groupBox5.TabIndex = 11; this.groupBox5.TabStop = false; this.groupBox5.Text = "Torrent-клиенты"; @@ -1199,127 +569,32 @@ private void InitializeComponent() this._btTorrentClientDelete.UseVisualStyleBackColor = true; this._btTorrentClientDelete.Click += new System.EventHandler(this.ClickButtons); // - // groupBox3 - // - this.groupBox3.Controls.Add(this._tcrbRemote); - this.groupBox3.Controls.Add(this._tcrbCurrent); - this.groupBox3.Controls.Add(this._tbTorrentClientHostIP); - this.groupBox3.Controls.Add(this.label7); - this.groupBox3.Controls.Add(this.label6); - this.groupBox3.Controls.Add(this._tbTorrentClientUserPassword); - this.groupBox3.Controls.Add(this._tbTorrentClientUserName); - this.groupBox3.Controls.Add(this._tbTorrentClientPort); - this.groupBox3.Controls.Add(this.label5); - this.groupBox3.Location = new System.Drawing.Point(255, 98); - this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(636, 151); - this.groupBox3.TabIndex = 8; - this.groupBox3.TabStop = false; - this.groupBox3.Text = "Доступ к torrent-клиенту"; - // - // _tcrbRemote - // - this._tcrbRemote.AutoSize = true; - this._tcrbRemote.Location = new System.Drawing.Point(9, 43); - this._tcrbRemote.Name = "_tcrbRemote"; - this._tcrbRemote.Size = new System.Drawing.Size(211, 17); - this._tcrbRemote.TabIndex = 9; - this._tcrbRemote.Text = "На другом компьютере, его имя/IP: "; - this._tcrbRemote.UseVisualStyleBackColor = true; - this._tcrbRemote.CheckedChanged += new System.EventHandler(this._Focus_Enter); - // - // _tcrbCurrent - // - this._tcrbCurrent.AutoSize = true; - this._tcrbCurrent.Checked = true; - this._tcrbCurrent.Location = new System.Drawing.Point(9, 20); - this._tcrbCurrent.Name = "_tcrbCurrent"; - this._tcrbCurrent.Size = new System.Drawing.Size(150, 17); - this._tcrbCurrent.TabIndex = 8; - this._tcrbCurrent.TabStop = true; - this._tcrbCurrent.Text = "На этом же компьютере"; - this._tcrbCurrent.UseVisualStyleBackColor = true; - this._tcrbCurrent.CheckedChanged += new System.EventHandler(this._Focus_Enter); - // - // _tbTorrentClientHostIP - // - this._tbTorrentClientHostIP.Location = new System.Drawing.Point(226, 42); - this._tbTorrentClientHostIP.Name = "_tbTorrentClientHostIP"; - this._tbTorrentClientHostIP.Size = new System.Drawing.Size(150, 20); - this._tbTorrentClientHostIP.TabIndex = 6; - this._tbTorrentClientHostIP.Enter += new System.EventHandler(this._Focus_Enter); - this._tbTorrentClientHostIP.Leave += new System.EventHandler(this._Focus_Enter); - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(6, 123); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(199, 13); - this.label7.TabIndex = 5; - this.label7.Text = "Пароль пользователя torrent-клиента:"; - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(6, 97); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(183, 13); - this.label6.TabIndex = 4; - this.label6.Text = "Имя пользователя torrent-клиента:"; - // - // _tbTorrentClientUserPassword - // - this._tbTorrentClientUserPassword.Location = new System.Drawing.Point(226, 120); - this._tbTorrentClientUserPassword.Name = "_tbTorrentClientUserPassword"; - this._tbTorrentClientUserPassword.PasswordChar = '*'; - this._tbTorrentClientUserPassword.Size = new System.Drawing.Size(150, 20); - this._tbTorrentClientUserPassword.TabIndex = 3; - this._tbTorrentClientUserPassword.Enter += new System.EventHandler(this._Focus_Enter); - this._tbTorrentClientUserPassword.Leave += new System.EventHandler(this._Focus_Enter); - // - // _tbTorrentClientUserName - // - this._tbTorrentClientUserName.Location = new System.Drawing.Point(226, 94); - this._tbTorrentClientUserName.Name = "_tbTorrentClientUserName"; - this._tbTorrentClientUserName.Size = new System.Drawing.Size(150, 20); - this._tbTorrentClientUserName.TabIndex = 2; - this._tbTorrentClientUserName.Enter += new System.EventHandler(this._Focus_Enter); - this._tbTorrentClientUserName.Leave += new System.EventHandler(this._Focus_Enter); - // - // _tbTorrentClientPort - // - this._tbTorrentClientPort.Location = new System.Drawing.Point(226, 68); - this._tbTorrentClientPort.Name = "_tbTorrentClientPort"; - this._tbTorrentClientPort.Size = new System.Drawing.Size(150, 20); - this._tbTorrentClientPort.TabIndex = 1; - this._tbTorrentClientPort.Enter += new System.EventHandler(this._Focus_Enter); - this._tbTorrentClientPort.Leave += new System.EventHandler(this._Focus_Enter); - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(6, 71); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(147, 13); - this.label5.TabIndex = 0; - this.label5.Text = "Порт Web/API-интерфейса:"; - // // dgwTorrentClients // this.dgwTorrentClients.AllowUserToAddRows = false; + this.dgwTorrentClients.AllowUserToDeleteRows = false; this.dgwTorrentClients.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); + this.dgwTorrentClients.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; + this.dgwTorrentClients.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.dgwTorrentClients.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dgwTorrentClients.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.UID, - this.FolderName}); + this.TorrentClientType, + this.FolderName, + this.TorrentClientHost, + this.TorrentClientPort, + this.TorrentClientUsername, + this.TorrentClientPassword, + this.TorrentClientStatus, + this.TorrentClientRemove}); this.dgwTorrentClients.Location = new System.Drawing.Point(6, 48); this.dgwTorrentClients.MultiSelect = false; this.dgwTorrentClients.Name = "dgwTorrentClients"; this.dgwTorrentClients.RowHeadersVisible = false; - this.dgwTorrentClients.Size = new System.Drawing.Size(240, 306); + this.dgwTorrentClients.Size = new System.Drawing.Size(949, 530); this.dgwTorrentClients.TabIndex = 0; + this.dgwTorrentClients.VirtualMode = true; this.dgwTorrentClients.SelectionChanged += new System.EventHandler(this.SelectionChanged); // // UID @@ -1328,59 +603,57 @@ private void InitializeComponent() this.UID.HeaderText = "UID"; this.UID.Name = "UID"; this.UID.ReadOnly = true; - this.UID.Visible = false; + // + // TorrentClientType + // + this.TorrentClientType.DataPropertyName = "Type"; + this.TorrentClientType.HeaderText = "Тип"; + this.TorrentClientType.Name = "TorrentClientType"; // // FolderName // - this.FolderName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; this.FolderName.DataPropertyName = "Name"; - this.FolderName.HeaderText = "Настройки"; + this.FolderName.HeaderText = "Имя"; + this.FolderName.MinimumWidth = 100; this.FolderName.Name = "FolderName"; - this.FolderName.ReadOnly = true; - // - // _cbTorrentClientType - // - this._cbTorrentClientType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this._cbTorrentClientType.FormattingEnabled = true; - this._cbTorrentClientType.Items.AddRange(new object[] { - "uTorrent", - "Transmission", - "Vuze (Vuze Web Remote)"}); - this._cbTorrentClientType.Location = new System.Drawing.Point(481, 71); - this._cbTorrentClientType.Name = "_cbTorrentClientType"; - this._cbTorrentClientType.Size = new System.Drawing.Size(121, 21); - this._cbTorrentClientType.TabIndex = 6; - this._cbTorrentClientType.Enter += new System.EventHandler(this._Focus_Enter); - this._cbTorrentClientType.Leave += new System.EventHandler(this._Focus_Enter); - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(252, 74); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(103, 13); - this.label2.TabIndex = 7; - this.label2.Text = "Тип torrent-клиента"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(252, 48); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(226, 13); - this.label1.TabIndex = 5; - this.label1.Text = "Название группы настроек torrent-клиента:"; - // - // _tbTorrentClientName - // - this._tbTorrentClientName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._tbTorrentClientName.Location = new System.Drawing.Point(481, 45); - this._tbTorrentClientName.Name = "_tbTorrentClientName"; - this._tbTorrentClientName.Size = new System.Drawing.Size(539, 20); - this._tbTorrentClientName.TabIndex = 4; - this._tbTorrentClientName.Enter += new System.EventHandler(this._Focus_Enter); - this._tbTorrentClientName.Leave += new System.EventHandler(this._Focus_Enter); + // + // TorrentClientHost + // + this.TorrentClientHost.DataPropertyName = "ServerName"; + this.TorrentClientHost.HeaderText = "Хост"; + this.TorrentClientHost.Name = "TorrentClientHost"; + // + // TorrentClientPort + // + this.TorrentClientPort.DataPropertyName = "ServerPort"; + this.TorrentClientPort.HeaderText = "Порт"; + this.TorrentClientPort.Name = "TorrentClientPort"; + // + // TorrentClientUsername + // + this.TorrentClientUsername.DataPropertyName = "UserName"; + this.TorrentClientUsername.HeaderText = "Логин"; + this.TorrentClientUsername.Name = "TorrentClientUsername"; + // + // TorrentClientPassword + // + this.TorrentClientPassword.HeaderText = "Пароль"; + this.TorrentClientPassword.Name = "TorrentClientPassword"; + // + // TorrentClientStatus + // + this.TorrentClientStatus.HeaderText = "Статус"; + this.TorrentClientStatus.Name = "TorrentClientStatus"; + this.TorrentClientStatus.ReadOnly = true; + // + // TorrentClientRemove + // + this.TorrentClientRemove.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.TorrentClientRemove.HeaderText = "Действие"; + this.TorrentClientRemove.Name = "TorrentClientRemove"; + this.TorrentClientRemove.Text = "X"; + this.TorrentClientRemove.ToolTipText = "Удалить этот торрент-клиент"; + this.TorrentClientRemove.UseColumnTextForButtonValue = true; // // tabControl1 // @@ -1388,6 +661,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Controls.Add(this.templatesTabPage3); this.tabControl1.Controls.Add(this.tbpTorrentClients); this.tabControl1.Controls.Add(this._tpCategories); this.tabControl1.Controls.Add(this.tabPage1); @@ -1395,11 +669,15 @@ private void InitializeComponent() this.tabControl1.Location = new System.Drawing.Point(0, 0); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(1049, 617); + this.tabControl1.Size = new System.Drawing.Size(983, 617); + this.tabControl1.SizeMode = System.Windows.Forms.TabSizeMode.FillToRight; this.tabControl1.TabIndex = 0; // // tabPage2 // + this.tabPage2.BackColor = System.Drawing.Color.Transparent; + this.tabPage2.Controls.Add(this.groupBox10); + this.tabPage2.Controls.Add(this.groupBox9); this.tabPage2.Controls.Add(this.groupBox8); this.tabPage2.Controls.Add(this.groupBox4); this.tabPage2.Controls.Add(this.groupBox2); @@ -1407,321 +685,352 @@ private void InitializeComponent() this.tabPage2.Location = new System.Drawing.Point(4, 22); this.tabPage2.Name = "tabPage2"; this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(1041, 591); + this.tabPage2.Size = new System.Drawing.Size(975, 591); this.tabPage2.TabIndex = 6; this.tabPage2.Text = "Основные настройки"; - this.tabPage2.UseVisualStyleBackColor = true; + // + // groupBox10 + // + this.groupBox10.Controls.Add(this.label47); + this.groupBox10.Controls.Add(this.showNotificationInTray); + this.groupBox10.Controls.Add(this.showTrayIcon); + this.groupBox10.Controls.Add(this.closeToTray); + this.groupBox10.Controls.Add(this.hideToTray); + this.groupBox10.Location = new System.Drawing.Point(8, 402); + this.groupBox10.Name = "groupBox10"; + this.groupBox10.Size = new System.Drawing.Size(367, 108); + this.groupBox10.TabIndex = 18; + this.groupBox10.TabStop = false; + this.groupBox10.Text = "Трей"; + // + // label47 + // + this.label47.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label47.Location = new System.Drawing.Point(3, 62); + this.label47.Name = "label47"; + this.label47.Size = new System.Drawing.Size(353, 43); + this.label47.TabIndex = 21; + this.label47.Text = "Если включить сворачивание или закрытие в трей, то кнопка в панели задач соответс" + + "твенно будет исчезать, так как программа будет переходить в трей."; + // + // showNotificationInTray + // + this.showNotificationInTray.AutoSize = true; + this.showNotificationInTray.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TLO.Properties.Settings.Default, "NotificationInTray", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.showNotificationInTray.Location = new System.Drawing.Point(176, 40); + this.showNotificationInTray.Name = "showNotificationInTray"; + this.showNotificationInTray.Size = new System.Drawing.Size(131, 17); + this.showNotificationInTray.TabIndex = 20; + this.showNotificationInTray.Text = "Уведомления в трее"; + this.showNotificationInTray.UseVisualStyleBackColor = true; + // + // showTrayIcon + // + this.showTrayIcon.AutoSize = true; + this.showTrayIcon.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TLO.Properties.Settings.Default, "ShowInTray", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.showTrayIcon.Location = new System.Drawing.Point(8, 17); + this.showTrayIcon.Name = "showTrayIcon"; + this.showTrayIcon.Size = new System.Drawing.Size(162, 17); + this.showTrayIcon.TabIndex = 19; + this.showTrayIcon.Text = "Показывать значок в трее"; + this.showTrayIcon.UseVisualStyleBackColor = true; + // + // closeToTray + // + this.closeToTray.AutoSize = true; + this.closeToTray.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TLO.Properties.Settings.Default, "CloseToTray", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.closeToTray.Location = new System.Drawing.Point(176, 17); + this.closeToTray.Name = "closeToTray"; + this.closeToTray.Size = new System.Drawing.Size(117, 17); + this.closeToTray.TabIndex = 1; + this.closeToTray.Text = "Закрывать в трей"; + this.closeToTray.UseVisualStyleBackColor = true; + // + // hideToTray + // + this.hideToTray.AutoSize = true; + this.hideToTray.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::TLO.Properties.Settings.Default, "HideToTray", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.hideToTray.Location = new System.Drawing.Point(6, 40); + this.hideToTray.Name = "hideToTray"; + this.hideToTray.Size = new System.Drawing.Size(126, 17); + this.hideToTray.TabIndex = 0; + this.hideToTray.Text = "Сворачивать в трей"; + this.hideToTray.UseVisualStyleBackColor = true; + // + // groupBox9 + // + this.groupBox9.AutoSize = true; + this.groupBox9.Controls.Add(this.rutrackerHost); + this.groupBox9.Controls.Add(this.label48); + this.groupBox9.Controls.Add(this.connectionCheck); + this.groupBox9.Controls.Add(this.SystemProxy); + this.groupBox9.Controls.Add(this.ProxyAddButton); + this.groupBox9.Controls.Add(this.ProxyListBox); + this.groupBox9.Controls.Add(this.DisableCertVerifyCheck); + this.groupBox9.Controls.Add(this.useProxyCheckBox); + this.groupBox9.Controls.Add(this.label41); + this.groupBox9.Controls.Add(this.apiHosts); + this.groupBox9.Controls.Add(this.proxyInput); + this.groupBox9.Controls.Add(this.label42); + this.groupBox9.Location = new System.Drawing.Point(381, 181); + this.groupBox9.Name = "groupBox9"; + this.groupBox9.Size = new System.Drawing.Size(593, 190); + this.groupBox9.TabIndex = 17; + this.groupBox9.TabStop = false; + this.groupBox9.Text = "Сеть и прокси"; + // + // rutrackerHost + // + this.rutrackerHost.Location = new System.Drawing.Point(8, 41); + this.rutrackerHost.Name = "rutrackerHost"; + this.rutrackerHost.Size = new System.Drawing.Size(286, 20); + this.rutrackerHost.TabIndex = 31; + // + // label48 + // + this.label48.AutoSize = true; + this.label48.Location = new System.Drawing.Point(8, 20); + this.label48.Name = "label48"; + this.label48.Size = new System.Drawing.Size(89, 13); + this.label48.TabIndex = 30; + this.label48.Text = "Хост рутрекера:"; + // + // connectionCheck + // + this.connectionCheck.AutoSize = true; + this.connectionCheck.BackColor = System.Drawing.Color.DarkOrange; + this.connectionCheck.Location = new System.Drawing.Point(8, 160); + this.connectionCheck.Name = "connectionCheck"; + this.connectionCheck.Size = new System.Drawing.Size(73, 13); + this.connectionCheck.TabIndex = 29; + this.connectionCheck.Text = "Состояние: ?"; + // + // SystemProxy + // + this.SystemProxy.Location = new System.Drawing.Point(182, 97); + this.SystemProxy.Name = "SystemProxy"; + this.SystemProxy.Size = new System.Drawing.Size(165, 21); + this.SystemProxy.TabIndex = 28; + this.SystemProxy.Text = "Системный прокси"; + this.SystemProxy.UseVisualStyleBackColor = true; + // + // ProxyAddButton + // + this.ProxyAddButton.Location = new System.Drawing.Point(321, 130); + this.ProxyAddButton.Name = "ProxyAddButton"; + this.ProxyAddButton.Size = new System.Drawing.Size(29, 22); + this.ProxyAddButton.TabIndex = 27; + this.ProxyAddButton.Text = ">>"; + this.ProxyAddButton.UseVisualStyleBackColor = true; + // + // ProxyListBox + // + this.ProxyListBox.AllowDrop = true; + this.ProxyListBox.FormattingEnabled = true; + this.ProxyListBox.Location = new System.Drawing.Point(356, 95); + this.ProxyListBox.Name = "ProxyListBox"; + this.ProxyListBox.Size = new System.Drawing.Size(227, 56); + this.ProxyListBox.TabIndex = 26; + // + // DisableCertVerifyCheck + // + this.DisableCertVerifyCheck.AutoSize = true; + this.DisableCertVerifyCheck.Location = new System.Drawing.Point(8, 68); + this.DisableCertVerifyCheck.Name = "DisableCertVerifyCheck"; + this.DisableCertVerifyCheck.Size = new System.Drawing.Size(247, 17); + this.DisableCertVerifyCheck.TabIndex = 23; + this.DisableCertVerifyCheck.Text = "Выключить проверку сертификата сервера"; + this.DisableCertVerifyCheck.UseVisualStyleBackColor = true; + // + // useProxyCheckBox + // + this.useProxyCheckBox.AutoSize = true; + this.useProxyCheckBox.Location = new System.Drawing.Point(8, 99); + this.useProxyCheckBox.Name = "useProxyCheckBox"; + this.useProxyCheckBox.Size = new System.Drawing.Size(138, 17); + this.useProxyCheckBox.TabIndex = 24; + this.useProxyCheckBox.Text = "Использовать прокси"; + this.useProxyCheckBox.UseVisualStyleBackColor = true; + // + // label41 + // + this.label41.AutoSize = true; + this.label41.Location = new System.Drawing.Point(5, 130); + this.label41.Name = "label41"; + this.label41.Size = new System.Drawing.Size(171, 13); + this.label41.TabIndex = 19; + this.label41.Text = "Добавить прокси (https, socks5):"; + // + // apiHosts + // + this.apiHosts.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.apiHosts.FormattingEnabled = true; + this.apiHosts.Items.AddRange(new object[] { + "api.t-ru.org", + "api.rutracker.org"}); + this.apiHosts.Location = new System.Drawing.Point(300, 40); + this.apiHosts.Name = "apiHosts"; + this.apiHosts.Size = new System.Drawing.Size(287, 21); + this.apiHosts.TabIndex = 21; + // + // proxyInput + // + this.proxyInput.AutoCompleteCustomSource.AddRange(new string[] { + "https://", + "socks5://"}); + this.proxyInput.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + this.proxyInput.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + this.proxyInput.Font = new System.Drawing.Font("Verdana", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.proxyInput.Location = new System.Drawing.Point(182, 130); + this.proxyInput.Name = "proxyInput"; + this.proxyInput.Size = new System.Drawing.Size(133, 22); + this.proxyInput.TabIndex = 18; + // + // label42 + // + this.label42.AutoSize = true; + this.label42.Location = new System.Drawing.Point(297, 20); + this.label42.Name = "label42"; + this.label42.Size = new System.Drawing.Size(109, 13); + this.label42.TabIndex = 20; + this.label42.Text = "Хост API рутрекера:"; // // groupBox8 // - this.groupBox8.Controls.Add(this.label39); - this.groupBox8.Controls.Add(this.label38); - this.groupBox8.Controls.Add(this.label37); - this.groupBox8.Controls.Add(this.label36); - this.groupBox8.Controls.Add(this.label35); - this.groupBox8.Controls.Add(this.label34); - this.groupBox8.Controls.Add(this.label33); - this.groupBox8.Controls.Add(this.label32); - this.groupBox8.Controls.Add(this._appReportBottom); - this.groupBox8.Controls.Add(this.label31); - this.groupBox8.Controls.Add(this.label30); - this.groupBox8.Controls.Add(this._appReportTop2); - this.groupBox8.Controls.Add(this._appReportTop1); - this.groupBox8.Controls.Add(this.label29); - this.groupBox8.Controls.Add(this.label28); - this.groupBox8.Controls.Add(this.label27); - this.groupBox8.Controls.Add(this.label26); - this.groupBox8.Controls.Add(this.label25); - this.groupBox8.Controls.Add(this.label24); - this.groupBox8.Controls.Add(this._appReportLine); - this.groupBox8.Controls.Add(this.label17); + this.groupBox8.AutoSize = true; this.groupBox8.Controls.Add(this.label9); this.groupBox8.Controls.Add(this._appCountSeedersReport); this.groupBox8.Controls.Add(this.label19); this.groupBox8.Location = new System.Drawing.Point(381, 6); this.groupBox8.Name = "groupBox8"; - this.groupBox8.Size = new System.Drawing.Size(653, 485); + this.groupBox8.Size = new System.Drawing.Size(591, 72); this.groupBox8.TabIndex = 3; this.groupBox8.TabStop = false; this.groupBox8.Text = "Настройки отчетов"; // - // label39 + // label9 // - this.label39.AutoSize = true; - this.label39.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label39.Location = new System.Drawing.Point(229, 366); - this.label39.Name = "label39"; - this.label39.Size = new System.Drawing.Size(177, 13); - this.label39.TabIndex = 31; - this.label39.Text = "%%ReportLines%% - Строки отчета"; + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(6, 21); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(431, 13); + this.label9.TabIndex = 9; + this.label9.Text = "В отчете о сидируемых раздачах отображаются раздачи с кол-вом сидов не более:"; // - // label38 + // _appCountSeedersReport // - this.label38.AutoSize = true; - this.label38.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label38.Location = new System.Drawing.Point(229, 353); - this.label38.Name = "label38"; - this.label38.Size = new System.Drawing.Size(228, 13); - this.label38.TabIndex = 30; - this.label38.Text = "%%NumberTopicsLast%% - Последний номер"; + this._appCountSeedersReport.Location = new System.Drawing.Point(459, 19); + this._appCountSeedersReport.Maximum = new decimal(new int[] { + 50, + 0, + 0, + 0}); + this._appCountSeedersReport.Minimum = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + this._appCountSeedersReport.Name = "_appCountSeedersReport"; + this._appCountSeedersReport.Size = new System.Drawing.Size(63, 20); + this._appCountSeedersReport.TabIndex = 9; + this._appCountSeedersReport.Value = new decimal(new int[] { + 10, + 0, + 0, + 0}); // - // label37 + // label19 // - this.label37.AutoSize = true; - this.label37.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label37.Location = new System.Drawing.Point(229, 339); - this.label37.Name = "label37"; - this.label37.Size = new System.Drawing.Size(228, 13); - this.label37.TabIndex = 29; - this.label37.Text = "%%NumberTopicsFirst%% - Начальный номер"; + this.label19.AutoSize = true; + this.label19.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label19.Location = new System.Drawing.Point(6, 42); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(557, 13); + this.label19.TabIndex = 10; + this.label19.Text = "Если требуется чтобы в отчет попадали все раздачи указанной категории, требуется " + + "указать значение \"-1\""; // - // label36 + // groupBox4 // - this.label36.AutoSize = true; - this.label36.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label36.Location = new System.Drawing.Point(229, 326); - this.label36.Name = "label36"; - this.label36.Size = new System.Drawing.Size(197, 13); - this.label36.TabIndex = 28; - this.label36.Text = "%%Top1%% - Вписать первый шаблон"; + this.groupBox4.Controls.Add(this.closeProgramCopies); + this.groupBox4.Controls.Add(this._appCountDaysKeepHistory); + this.groupBox4.Controls.Add(this.label46); + this.groupBox4.Controls.Add(this.label10); + this.groupBox4.Controls.Add(this._dbLoadInMemoryCheckbox); + this.groupBox4.Controls.Add(this._appIsNotSaveStatistics); + this.groupBox4.Controls.Add(this.label23); + this.groupBox4.Controls.Add(this._appLogLevel); + this.groupBox4.Controls.Add(this.label21); + this.groupBox4.Controls.Add(this.label12); + this.groupBox4.Controls.Add(this._appIsUpdateStatistics); + this.groupBox4.Controls.Add(this._appPeriodRunAndStopTorrents); + this.groupBox4.Controls.Add(this.label11); + this.groupBox4.Location = new System.Drawing.Point(8, 84); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(367, 312); + this.groupBox4.TabIndex = 2; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Настройки программы"; // - // label35 + // closeProgramCopies // - this.label35.AutoSize = true; - this.label35.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label35.Location = new System.Drawing.Point(6, 352); - this.label35.Name = "label35"; - this.label35.Size = new System.Drawing.Size(196, 13); - this.label35.TabIndex = 27; - this.label35.Text = "%%SizeTopics%% - Размер хранимого"; + this.closeProgramCopies.AutoSize = true; + this.closeProgramCopies.Location = new System.Drawing.Point(9, 285); + this.closeProgramCopies.Name = "closeProgramCopies"; + this.closeProgramCopies.Size = new System.Drawing.Size(310, 17); + this.closeProgramCopies.TabIndex = 19; + this.closeProgramCopies.Text = "При запуске программы закрывать ранее запущенные"; + this.closeProgramCopies.UseVisualStyleBackColor = true; // - // label34 + // _appCountDaysKeepHistory // - this.label34.AutoSize = true; - this.label34.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label34.Location = new System.Drawing.Point(6, 339); - this.label34.Name = "label34"; - this.label34.Size = new System.Drawing.Size(180, 13); - this.label34.TabIndex = 26; - this.label34.Text = "%%CountTopics%% - Кол-во раздач"; + this._appCountDaysKeepHistory.Location = new System.Drawing.Point(259, 125); + this._appCountDaysKeepHistory.Maximum = new decimal(new int[] { + 30, + 0, + 0, + 0}); + this._appCountDaysKeepHistory.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this._appCountDaysKeepHistory.Name = "_appCountDaysKeepHistory"; + this._appCountDaysKeepHistory.Size = new System.Drawing.Size(102, 20); + this._appCountDaysKeepHistory.TabIndex = 6; + this._appCountDaysKeepHistory.Value = new decimal(new int[] { + 7, + 0, + 0, + 0}); // - // label33 + // label46 // - this.label33.AutoSize = true; - this.label33.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label33.Location = new System.Drawing.Point(6, 326); - this.label33.Name = "label33"; - this.label33.Size = new System.Drawing.Size(196, 13); - this.label33.TabIndex = 25; - this.label33.Text = "%%CreateDate%% - Дата составления"; + this.label46.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label46.Location = new System.Drawing.Point(6, 239); + this.label46.Name = "label46"; + this.label46.Size = new System.Drawing.Size(355, 42); + this.label46.TabIndex = 18; + this.label46.Text = "Загрузка БД в оперативную память позволяет ускорить операции формирования отчетов" + + " и фильтрации списка раздач. Имеет смысл включать эту опцию если фильтрация спис" + + "ка в TLO тормозит."; // - // label32 + // label10 // - this.label32.AutoSize = true; - this.label32.Location = new System.Drawing.Point(6, 382); - this.label32.Name = "label32"; - this.label32.Size = new System.Drawing.Size(94, 13); - this.label32.TabIndex = 24; - this.label32.Text = "Шаблон подвала:"; - // - // _appReportBottom - // - this._appReportBottom.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._appReportBottom.Location = new System.Drawing.Point(6, 398); - this._appReportBottom.Multiline = true; - this._appReportBottom.Name = "_appReportBottom"; - this._appReportBottom.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this._appReportBottom.Size = new System.Drawing.Size(638, 79); - this._appReportBottom.TabIndex = 23; - // - // label31 - // - this.label31.AutoSize = true; - this.label31.Location = new System.Drawing.Point(6, 228); - this.label31.Name = "label31"; - this.label31.Size = new System.Drawing.Size(162, 13); - this.label31.TabIndex = 22; - this.label31.Text = "Шаблон общей шапки отчетов:"; - // - // label30 - // - this.label30.AutoSize = true; - this.label30.Location = new System.Drawing.Point(6, 127); - this.label30.Name = "label30"; - this.label30.Size = new System.Drawing.Size(164, 13); - this.label30.TabIndex = 21; - this.label30.Text = "Шаблон шапки первого отчета:"; - // - // _appReportTop2 - // - this._appReportTop2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._appReportTop2.Location = new System.Drawing.Point(9, 244); - this._appReportTop2.Multiline = true; - this._appReportTop2.Name = "_appReportTop2"; - this._appReportTop2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this._appReportTop2.Size = new System.Drawing.Size(638, 79); - this._appReportTop2.TabIndex = 20; - // - // _appReportTop1 - // - this._appReportTop1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._appReportTop1.Location = new System.Drawing.Point(9, 143); - this._appReportTop1.Multiline = true; - this._appReportTop1.Name = "_appReportTop1"; - this._appReportTop1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this._appReportTop1.Size = new System.Drawing.Size(638, 79); - this._appReportTop1.TabIndex = 19; - // - // label29 - // - this.label29.AutoSize = true; - this.label29.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label29.Location = new System.Drawing.Point(390, 110); - this.label29.Name = "label29"; - this.label29.Size = new System.Drawing.Size(161, 13); - this.label29.TabIndex = 18; - this.label29.Text = "%%Date%% - дата регистрации"; - // - // label28 - // - this.label28.AutoSize = true; - this.label28.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label28.Location = new System.Drawing.Point(390, 98); - this.label28.Name = "label28"; - this.label28.Size = new System.Drawing.Size(181, 13); - this.label28.TabIndex = 17; - this.label28.Text = "%%CountSeeders%% - кол-во сидов"; - // - // label27 - // - this.label27.AutoSize = true; - this.label27.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label27.Location = new System.Drawing.Point(229, 98); - this.label27.Name = "label27"; - this.label27.Size = new System.Drawing.Size(151, 13); - this.label27.TabIndex = 16; - this.label27.Text = "%%Size%% - Размер раздачи"; - // - // label26 - // - this.label26.AutoSize = true; - this.label26.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label26.Location = new System.Drawing.Point(229, 111); - this.label26.Name = "label26"; - this.label26.Size = new System.Drawing.Size(155, 13); - this.label26.TabIndex = 15; - this.label26.Text = "%%Status%% - статус раздачи"; - // - // label25 - // - this.label25.AutoSize = true; - this.label25.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label25.Location = new System.Drawing.Point(6, 110); - this.label25.Name = "label25"; - this.label25.Size = new System.Drawing.Size(194, 13); - this.label25.TabIndex = 14; - this.label25.Text = "%%Name%% - наименование раздачи"; - // - // label24 - // - this.label24.AutoSize = true; - this.label24.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label24.Location = new System.Drawing.Point(6, 97); - this.label24.Name = "label24"; - this.label24.Size = new System.Drawing.Size(181, 13); - this.label24.TabIndex = 13; - this.label24.Text = "%%ID%% - идентификатор раздачи"; - // - // _appReportLine - // - this._appReportLine.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this._appReportLine.Location = new System.Drawing.Point(9, 75); - this._appReportLine.Name = "_appReportLine"; - this._appReportLine.Size = new System.Drawing.Size(638, 20); - this._appReportLine.TabIndex = 12; - // - // label17 - // - this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(6, 59); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(123, 13); - this.label17.TabIndex = 11; - this.label17.Text = "Шаблон строки отчета:"; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(6, 21); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(431, 13); - this.label9.TabIndex = 9; - this.label9.Text = "В отчете о сидируемых раздачах отображаются раздачи с кол-вом сидов не более:"; - // - // _appCountSeedersReport - // - this._appCountSeedersReport.Location = new System.Drawing.Point(443, 19); - this._appCountSeedersReport.Maximum = new decimal(new int[] { - 50, - 0, - 0, - 0}); - this._appCountSeedersReport.Minimum = new decimal(new int[] { - 1, - 0, - 0, - -2147483648}); - this._appCountSeedersReport.Name = "_appCountSeedersReport"; - this._appCountSeedersReport.Size = new System.Drawing.Size(63, 20); - this._appCountSeedersReport.TabIndex = 9; - this._appCountSeedersReport.Value = new decimal(new int[] { - 10, - 0, - 0, - 0}); - // - // label19 - // - this.label19.AutoSize = true; - this.label19.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label19.Location = new System.Drawing.Point(6, 42); - this.label19.Name = "label19"; - this.label19.Size = new System.Drawing.Size(560, 13); - this.label19.TabIndex = 10; - this.label19.Text = "Если требуется чтобы в отчет попадали все раздачи указанной категории, требуется" + - " указать значение \"-1\""; - // - // groupBox4 - // - this.groupBox4.Controls.Add(this._dbLoadInMemoryCheckbox); - this.groupBox4.Controls.Add(this._appIsNotSaveStatistics); - this.groupBox4.Controls.Add(this.label23); - this.groupBox4.Controls.Add(this._appLogLevel); - this.groupBox4.Controls.Add(this.label21); - this.groupBox4.Controls.Add(this.label20); - this.groupBox4.Controls.Add(this._appSelectLessOrEqual); - this.groupBox4.Controls.Add(this.label12); - this.groupBox4.Controls.Add(this._appIsUpdateStatistics); - this.groupBox4.Controls.Add(this._appPeriodRunAndStopTorrents); - this.groupBox4.Controls.Add(this.label11); - this.groupBox4.Location = new System.Drawing.Point(8, 161); - this.groupBox4.Name = "groupBox4"; - this.groupBox4.Size = new System.Drawing.Size(367, 415); - this.groupBox4.TabIndex = 2; - this.groupBox4.TabStop = false; - this.groupBox4.Text = "Настройки программы"; + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(3, 127); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(206, 13); + this.label10.TabIndex = 1; + this.label10.Text = "Хранить историю о кол-ве сидов, дней:"; // // _dbLoadInMemoryCheckbox // - this._dbLoadInMemoryCheckbox.Location = new System.Drawing.Point(6, 244); + this._dbLoadInMemoryCheckbox.Location = new System.Drawing.Point(6, 219); this._dbLoadInMemoryCheckbox.Name = "_dbLoadInMemoryCheckbox"; this._dbLoadInMemoryCheckbox.Size = new System.Drawing.Size(219, 17); this._dbLoadInMemoryCheckbox.TabIndex = 17; - this._dbLoadInMemoryCheckbox.Text = "Выгружать БД в оперативную память"; + this._dbLoadInMemoryCheckbox.Text = "Загружать БД в оперативную память"; this._dbLoadInMemoryCheckbox.UseVisualStyleBackColor = true; this._dbLoadInMemoryCheckbox.Click += new System.EventHandler(this.ClickButtons); // @@ -1739,55 +1048,34 @@ private void InitializeComponent() // label23 // this.label23.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label23.Location = new System.Drawing.Point(6, 198); + this.label23.Location = new System.Drawing.Point(6, 174); this.label23.Name = "label23"; this.label23.Size = new System.Drawing.Size(355, 42); this.label23.TabIndex = 15; - this.label23.Text = "Отвечает за подробность ведения текстового лога. 0 - ошибки/предупреждения, 1 - +" + - "информационные сообщения, 2 - + отладочные сообщения, 3 - + шаги выполнения прог" + - "раммы"; + this.label23.Text = "Отвечает за подробность ведения текстового лога. 0 - ошибки, 1 - информационные л" + + "оги, 2 - подробные логи, 3 - все логи а также ответы от сервера."; // // _appLogLevel // - this._appLogLevel.Location = new System.Drawing.Point(298, 175); + this._appLogLevel.Location = new System.Drawing.Point(259, 151); this._appLogLevel.Maximum = new decimal(new int[] { 5, 0, 0, 0}); this._appLogLevel.Name = "_appLogLevel"; - this._appLogLevel.Size = new System.Drawing.Size(63, 20); + this._appLogLevel.Size = new System.Drawing.Size(102, 20); this._appLogLevel.TabIndex = 14; // // label21 // this.label21.AutoSize = true; - this.label21.Location = new System.Drawing.Point(6, 177); + this.label21.Location = new System.Drawing.Point(3, 153); this.label21.Name = "label21"; this.label21.Size = new System.Drawing.Size(231, 13); this.label21.TabIndex = 13; this.label21.Text = "Уровень ведения логов (значение от 0 до 3)"; // - // label20 - // - this.label20.ForeColor = System.Drawing.SystemColors.ControlDark; - this.label20.Location = new System.Drawing.Point(6, 142); - this.label20.Name = "label20"; - this.label20.Size = new System.Drawing.Size(355, 30); - this.label20.TabIndex = 12; - this.label20.Text = "Если флаг не установлен, то на главной форме будет использоваться строгое соответ" + - "ствие указаному значению"; - // - // _appSelectLessOrEqual - // - this._appSelectLessOrEqual.AutoSize = true; - this._appSelectLessOrEqual.Location = new System.Drawing.Point(6, 122); - this._appSelectLessOrEqual.Name = "_appSelectLessOrEqual"; - this._appSelectLessOrEqual.Size = new System.Drawing.Size(278, 17); - this._appSelectLessOrEqual.TabIndex = 11; - this._appSelectLessOrEqual.Text = "Использовать отбор как <= указанного значения"; - this._appSelectLessOrEqual.UseVisualStyleBackColor = true; - // // label12 // this.label12.ForeColor = System.Drawing.SystemColors.ControlDark; @@ -1841,59 +1129,48 @@ private void InitializeComponent() // // groupBox2 // - this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupBox2.Controls.Add(this._appCountDaysKeepHistory); - this.groupBox2.Controls.Add(this.label10); + this.groupBox2.AutoSize = true; this.groupBox2.Controls.Add(this._appIsAvgCountSeeders); - this.groupBox2.Location = new System.Drawing.Point(8, 84); + this.groupBox2.Controls.Add(this.label20); + this.groupBox2.Controls.Add(this._appSelectLessOrEqual); + this.groupBox2.Location = new System.Drawing.Point(382, 84); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(367, 71); + this.groupBox2.Size = new System.Drawing.Size(590, 92); this.groupBox2.TabIndex = 1; this.groupBox2.TabStop = false; this.groupBox2.Text = "Отбор раздач"; // - // _appCountDaysKeepHistory - // - this._appCountDaysKeepHistory.Location = new System.Drawing.Point(218, 42); - this._appCountDaysKeepHistory.Maximum = new decimal(new int[] { - 30, - 0, - 0, - 0}); - this._appCountDaysKeepHistory.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this._appCountDaysKeepHistory.Name = "_appCountDaysKeepHistory"; - this._appCountDaysKeepHistory.Size = new System.Drawing.Size(102, 20); - this._appCountDaysKeepHistory.TabIndex = 6; - this._appCountDaysKeepHistory.Value = new decimal(new int[] { - 7, - 0, - 0, - 0}); - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(6, 44); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(206, 13); - this.label10.TabIndex = 1; - this.label10.Text = "Хранить историю о кол-ве сидов, дней:"; - // // _appIsAvgCountSeeders // this._appIsAvgCountSeeders.AutoSize = true; this._appIsAvgCountSeeders.Location = new System.Drawing.Point(6, 19); this._appIsAvgCountSeeders.Name = "_appIsAvgCountSeeders"; - this._appIsAvgCountSeeders.Size = new System.Drawing.Size(302, 17); + this._appIsAvgCountSeeders.Size = new System.Drawing.Size(361, 17); this._appIsAvgCountSeeders.TabIndex = 0; - this._appIsAvgCountSeeders.Text = "Использовать отбор и сортировку по ср. кол-ву сидов"; + this._appIsAvgCountSeeders.Text = "Использовать отбор и сортировку по среднему количеству сидов"; this._appIsAvgCountSeeders.UseVisualStyleBackColor = true; // + // label20 + // + this.label20.AutoSize = true; + this.label20.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label20.Location = new System.Drawing.Point(6, 62); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(529, 13); + this.label20.TabIndex = 12; + this.label20.Text = "Если флаг не установлен, то раздачи будут отбираться строго соответсвующие указан" + + "ному значению"; + // + // _appSelectLessOrEqual + // + this._appSelectLessOrEqual.AutoSize = true; + this._appSelectLessOrEqual.Location = new System.Drawing.Point(6, 42); + this._appSelectLessOrEqual.Name = "_appSelectLessOrEqual"; + this._appSelectLessOrEqual.Size = new System.Drawing.Size(386, 17); + this._appSelectLessOrEqual.TabIndex = 11; + this._appSelectLessOrEqual.Text = "Использовать отбор по количеству сидов как <= указанного значения"; + this._appSelectLessOrEqual.UseVisualStyleBackColor = true; + // // groupBox1 // this.groupBox1.Controls.Add(this.label8); @@ -1944,13 +1221,358 @@ private void InitializeComponent() this.label4.TabIndex = 0; this.label4.Text = "Логин пользователя сайта:"; // + // templatesTabPage3 + // + this.templatesTabPage3.Controls.Add(this.tableLayoutPanel1); + this.templatesTabPage3.Controls.Add(this.label39); + this.templatesTabPage3.Controls.Add(this.label38); + this.templatesTabPage3.Controls.Add(this.label37); + this.templatesTabPage3.Controls.Add(this.label36); + this.templatesTabPage3.Controls.Add(this.label35); + this.templatesTabPage3.Controls.Add(this.label34); + this.templatesTabPage3.Controls.Add(this.label33); + this.templatesTabPage3.Controls.Add(this.label29); + this.templatesTabPage3.Controls.Add(this.label28); + this.templatesTabPage3.Controls.Add(this.label27); + this.templatesTabPage3.Controls.Add(this.label26); + this.templatesTabPage3.Controls.Add(this.label25); + this.templatesTabPage3.Controls.Add(this.label24); + this.templatesTabPage3.Location = new System.Drawing.Point(4, 22); + this.templatesTabPage3.Name = "templatesTabPage3"; + this.templatesTabPage3.Size = new System.Drawing.Size(975, 591); + this.templatesTabPage3.TabIndex = 8; + this.templatesTabPage3.Text = "Шаблоны"; + this.templatesTabPage3.UseVisualStyleBackColor = true; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel1.AutoSize = true; + this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel1.ColumnCount = 3; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33332F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F)); + this.tableLayoutPanel1.Controls.Add(this.label17, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.categoryReportTemplate, 0, 9); + this.tableLayoutPanel1.Controls.Add(this.reportHeaderTemplate, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.label44, 0, 8); + this.tableLayoutPanel1.Controls.Add(this._appReportLine, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.summaryReportTemplate, 0, 7); + this.tableLayoutPanel1.Controls.Add(this.label45, 2, 2); + this.tableLayoutPanel1.Controls.Add(this.label43, 0, 6); + this.tableLayoutPanel1.Controls.Add(this.label30, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.label31, 1, 2); + this.tableLayoutPanel1.Controls.Add(this._appReportTop1, 1, 3); + this.tableLayoutPanel1.Controls.Add(this._appReportTop2, 2, 3); + this.tableLayoutPanel1.Controls.Add(this.label32, 0, 4); + this.tableLayoutPanel1.Controls.Add(this._appReportBottom, 0, 5); + this.tableLayoutPanel1.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 10; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(926, 455); + this.tableLayoutPanel1.TabIndex = 59; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(3, 0); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(131, 13); + this.label17.TabIndex = 32; + this.label17.Text = "Строка отчета (устарел):"; + // + // categoryReportTemplate + // + this.tableLayoutPanel1.SetColumnSpan(this.categoryReportTemplate, 3); + this.categoryReportTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.categoryReportTemplate.Location = new System.Drawing.Point(3, 380); + this.categoryReportTemplate.Multiline = true; + this.categoryReportTemplate.Name = "categoryReportTemplate"; + this.categoryReportTemplate.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.categoryReportTemplate.Size = new System.Drawing.Size(920, 72); + this.categoryReportTemplate.TabIndex = 56; + // + // reportHeaderTemplate + // + this.reportHeaderTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.reportHeaderTemplate.Location = new System.Drawing.Point(3, 107); + this.reportHeaderTemplate.Multiline = true; + this.reportHeaderTemplate.Name = "reportHeaderTemplate"; + this.reportHeaderTemplate.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.reportHeaderTemplate.Size = new System.Drawing.Size(302, 72); + this.reportHeaderTemplate.TabIndex = 58; + // + // label44 + // + this.label44.AutoSize = true; + this.label44.Location = new System.Drawing.Point(3, 364); + this.label44.Name = "label44"; + this.label44.Size = new System.Drawing.Size(116, 13); + this.label44.TabIndex = 55; + this.label44.Text = "Отчет по подразделу:"; + // + // _appReportLine + // + this.tableLayoutPanel1.SetColumnSpan(this._appReportLine, 3); + this._appReportLine.Dock = System.Windows.Forms.DockStyle.Fill; + this._appReportLine.Location = new System.Drawing.Point(3, 16); + this._appReportLine.Multiline = true; + this._appReportLine.Name = "_appReportLine"; + this._appReportLine.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._appReportLine.Size = new System.Drawing.Size(920, 72); + this._appReportLine.TabIndex = 33; + // + // summaryReportTemplate + // + this.tableLayoutPanel1.SetColumnSpan(this.summaryReportTemplate, 3); + this.summaryReportTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.summaryReportTemplate.Location = new System.Drawing.Point(3, 289); + this.summaryReportTemplate.Multiline = true; + this.summaryReportTemplate.Name = "summaryReportTemplate"; + this.summaryReportTemplate.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.summaryReportTemplate.Size = new System.Drawing.Size(920, 72); + this.summaryReportTemplate.TabIndex = 54; + // + // label45 + // + this.label45.AutoSize = true; + this.label45.Location = new System.Drawing.Point(619, 91); + this.label45.Name = "label45"; + this.label45.Size = new System.Drawing.Size(234, 13); + this.label45.TabIndex = 57; + this.label45.Text = "Шапки каждого сообщения отчета (устарел):"; + // + // label43 + // + this.label43.AutoSize = true; + this.label43.Location = new System.Drawing.Point(3, 273); + this.label43.Name = "label43"; + this.label43.Size = new System.Drawing.Size(85, 13); + this.label43.TabIndex = 53; + this.label43.Text = "Сводный отчет:"; + // + // label30 + // + this.label30.AutoSize = true; + this.label30.Location = new System.Drawing.Point(3, 91); + this.label30.Name = "label30"; + this.label30.Size = new System.Drawing.Size(143, 13); + this.label30.TabIndex = 42; + this.label30.Text = "Шапка списка хранителей:"; + // + // label31 + // + this.label31.AutoSize = true; + this.label31.Location = new System.Drawing.Point(311, 91); + this.label31.Name = "label31"; + this.label31.Size = new System.Drawing.Size(232, 13); + this.label31.TabIndex = 43; + this.label31.Text = "Шапка первого сообщения отчета (устарел):"; + // + // _appReportTop1 + // + this._appReportTop1.Dock = System.Windows.Forms.DockStyle.Fill; + this._appReportTop1.Location = new System.Drawing.Point(311, 107); + this._appReportTop1.Multiline = true; + this._appReportTop1.Name = "_appReportTop1"; + this._appReportTop1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._appReportTop1.Size = new System.Drawing.Size(302, 72); + this._appReportTop1.TabIndex = 40; + // + // _appReportTop2 + // + this._appReportTop2.Dock = System.Windows.Forms.DockStyle.Fill; + this._appReportTop2.Location = new System.Drawing.Point(619, 107); + this._appReportTop2.Multiline = true; + this._appReportTop2.Name = "_appReportTop2"; + this._appReportTop2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._appReportTop2.Size = new System.Drawing.Size(304, 72); + this._appReportTop2.TabIndex = 41; + // + // label32 + // + this.label32.AutoSize = true; + this.label32.Location = new System.Drawing.Point(3, 182); + this.label32.Name = "label32"; + this.label32.Size = new System.Drawing.Size(126, 13); + this.label32.TabIndex = 45; + this.label32.Text = "Конец отчета (устарел):"; + // + // _appReportBottom + // + this.tableLayoutPanel1.SetColumnSpan(this._appReportBottom, 3); + this._appReportBottom.Dock = System.Windows.Forms.DockStyle.Fill; + this._appReportBottom.Location = new System.Drawing.Point(3, 198); + this._appReportBottom.Multiline = true; + this._appReportBottom.Name = "_appReportBottom"; + this._appReportBottom.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._appReportBottom.Size = new System.Drawing.Size(920, 72); + this._appReportBottom.TabIndex = 44; + // + // label39 + // + this.label39.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label39.AutoSize = true; + this.label39.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label39.Location = new System.Drawing.Point(477, 540); + this.label39.Name = "label39"; + this.label39.Size = new System.Drawing.Size(177, 13); + this.label39.TabIndex = 52; + this.label39.Text = "%%ReportLines%% - Строки отчета"; + // + // label38 + // + this.label38.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label38.AutoSize = true; + this.label38.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label38.Location = new System.Drawing.Point(477, 527); + this.label38.Name = "label38"; + this.label38.Size = new System.Drawing.Size(228, 13); + this.label38.TabIndex = 51; + this.label38.Text = "%%NumberTopicsLast%% - Последний номер"; + // + // label37 + // + this.label37.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label37.AutoSize = true; + this.label37.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label37.Location = new System.Drawing.Point(477, 514); + this.label37.Name = "label37"; + this.label37.Size = new System.Drawing.Size(228, 13); + this.label37.TabIndex = 50; + this.label37.Text = "%%NumberTopicsFirst%% - Начальный номер"; + // + // label36 + // + this.label36.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label36.AutoSize = true; + this.label36.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label36.Location = new System.Drawing.Point(477, 501); + this.label36.Name = "label36"; + this.label36.Size = new System.Drawing.Size(197, 13); + this.label36.TabIndex = 49; + this.label36.Text = "%%Top1%% - Вписать первый шаблон"; + // + // label35 + // + this.label35.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label35.AutoSize = true; + this.label35.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label35.Location = new System.Drawing.Point(237, 527); + this.label35.Name = "label35"; + this.label35.Size = new System.Drawing.Size(196, 13); + this.label35.TabIndex = 48; + this.label35.Text = "%%SizeTopics%% - Размер хранимого"; + // + // label34 + // + this.label34.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label34.AutoSize = true; + this.label34.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label34.Location = new System.Drawing.Point(237, 514); + this.label34.Name = "label34"; + this.label34.Size = new System.Drawing.Size(180, 13); + this.label34.TabIndex = 47; + this.label34.Text = "%%CountTopics%% - Кол-во раздач"; + // + // label33 + // + this.label33.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label33.AutoSize = true; + this.label33.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label33.Location = new System.Drawing.Point(237, 501); + this.label33.Name = "label33"; + this.label33.Size = new System.Drawing.Size(196, 13); + this.label33.TabIndex = 46; + this.label33.Text = "%%CreateDate%% - Дата составления"; + // + // label29 + // + this.label29.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label29.AutoSize = true; + this.label29.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label29.Location = new System.Drawing.Point(5, 566); + this.label29.Name = "label29"; + this.label29.Size = new System.Drawing.Size(161, 13); + this.label29.TabIndex = 39; + this.label29.Text = "%%Date%% - дата регистрации"; + // + // label28 + // + this.label28.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label28.AutoSize = true; + this.label28.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label28.Location = new System.Drawing.Point(5, 553); + this.label28.Name = "label28"; + this.label28.Size = new System.Drawing.Size(181, 13); + this.label28.TabIndex = 38; + this.label28.Text = "%%CountSeeders%% - кол-во сидов"; + // + // label27 + // + this.label27.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label27.AutoSize = true; + this.label27.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label27.Location = new System.Drawing.Point(5, 527); + this.label27.Name = "label27"; + this.label27.Size = new System.Drawing.Size(151, 13); + this.label27.TabIndex = 37; + this.label27.Text = "%%Size%% - Размер раздачи"; + // + // label26 + // + this.label26.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label26.AutoSize = true; + this.label26.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label26.Location = new System.Drawing.Point(5, 540); + this.label26.Name = "label26"; + this.label26.Size = new System.Drawing.Size(155, 13); + this.label26.TabIndex = 36; + this.label26.Text = "%%Status%% - статус раздачи"; + // + // label25 + // + this.label25.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label25.AutoSize = true; + this.label25.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label25.Location = new System.Drawing.Point(5, 514); + this.label25.Name = "label25"; + this.label25.Size = new System.Drawing.Size(194, 13); + this.label25.TabIndex = 35; + this.label25.Text = "%%Name%% - наименование раздачи"; + // + // label24 + // + this.label24.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label24.AutoSize = true; + this.label24.ForeColor = System.Drawing.SystemColors.ControlDark; + this.label24.Location = new System.Drawing.Point(5, 501); + this.label24.Name = "label24"; + this.label24.Size = new System.Drawing.Size(181, 13); + this.label24.TabIndex = 34; + this.label24.Text = "%%ID%% - идентификатор раздачи"; + // // tabPage1 // this.tabPage1.Controls.Add(this.forumPages1); this.tabPage1.Location = new System.Drawing.Point(4, 22); this.tabPage1.Name = "tabPage1"; this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(1041, 591); + this.tabPage1.Size = new System.Drawing.Size(975, 591); this.tabPage1.TabIndex = 5; this.tabPage1.Text = "Отправка отчетов на форум"; this.tabPage1.UseVisualStyleBackColor = true; @@ -1962,7 +1584,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.forumPages1.Location = new System.Drawing.Point(0, 0); this.forumPages1.Name = "forumPages1"; - this.forumPages1.Size = new System.Drawing.Size(1041, 591); + this.forumPages1.Size = new System.Drawing.Size(975, 591); this.forumPages1.TabIndex = 0; // // _tpAllCategories @@ -1971,7 +1593,7 @@ private void InitializeComponent() this._tpAllCategories.Location = new System.Drawing.Point(4, 22); this._tpAllCategories.Name = "_tpAllCategories"; this._tpAllCategories.Padding = new System.Windows.Forms.Padding(3); - this._tpAllCategories.Size = new System.Drawing.Size(1041, 591); + this._tpAllCategories.Size = new System.Drawing.Size(975, 591); this._tpAllCategories.TabIndex = 7; this._tpAllCategories.Text = "Все категории"; this._tpAllCategories.UseVisualStyleBackColor = true; @@ -1984,20 +1606,23 @@ private void InitializeComponent() this.panel2.AutoScroll = true; this.panel2.Location = new System.Drawing.Point(0, 54); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(1041, 537); + this.panel2.Size = new System.Drawing.Size(975, 537); this.panel2.TabIndex = 0; // // SettingsForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1050, 649); + this.ClientSize = new System.Drawing.Size(984, 649); this.Controls.Add(this._btCancel); - this.Controls.Add(this._btCheck); this.Controls.Add(this._btSave); this.Controls.Add(this.tabControl1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MinimumSize = new System.Drawing.Size(1000, 688); this.Name = "SettingsForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Настройки"; + this.Load += new System.EventHandler(this.FormLoaded); this._tpCategories.ResumeLayout(false); this.panel1.ResumeLayout(false); this.groupBox7.ResumeLayout(false); @@ -2007,28 +1632,161 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.dgwCategories)).EndInit(); this.tbpTorrentClients.ResumeLayout(false); this.groupBox5.ResumeLayout(false); - this.groupBox5.PerformLayout(); - this.groupBox3.ResumeLayout(false); - this.groupBox3.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.dgwTorrentClients)).EndInit(); this.tabControl1.ResumeLayout(false); this.tabPage2.ResumeLayout(false); + this.tabPage2.PerformLayout(); + this.groupBox10.ResumeLayout(false); + this.groupBox10.PerformLayout(); + this.groupBox9.ResumeLayout(false); + this.groupBox9.PerformLayout(); this.groupBox8.ResumeLayout(false); this.groupBox8.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this._appCountSeedersReport)).EndInit(); this.groupBox4.ResumeLayout(false); this.groupBox4.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this._appCountDaysKeepHistory)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this._appLogLevel)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this._appPeriodRunAndStopTorrents)).EndInit(); this.groupBox2.ResumeLayout(false); this.groupBox2.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this._appCountDaysKeepHistory)).EndInit(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); + this.templatesTabPage3.ResumeLayout(false); + this.templatesTabPage3.PerformLayout(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); this.tabPage1.ResumeLayout(false); this._tpAllCategories.ResumeLayout(false); this.ResumeLayout(false); } + + private System.Windows.Forms.NumericUpDown _appCountDaysKeepHistory; + private System.Windows.Forms.NumericUpDown _appCountSeedersReport; + private System.Windows.Forms.CheckBox _appIsAvgCountSeeders; + private System.Windows.Forms.CheckBox _appIsNotSaveStatistics; + private System.Windows.Forms.CheckBox _appIsUpdateStatistics; + private System.Windows.Forms.TextBox _appKeeperName; + private System.Windows.Forms.TextBox _appKeeperPass; + private System.Windows.Forms.NumericUpDown _appLogLevel; + private System.Windows.Forms.NumericUpDown _appPeriodRunAndStopTorrents; + private System.Windows.Forms.TextBox _appReportBottom; + private System.Windows.Forms.TextBox _appReportLine; + private System.Windows.Forms.TextBox _appReportTop1; + private System.Windows.Forms.TextBox _appReportTop2; + private System.Windows.Forms.CheckBox _appSelectLessOrEqual; + private System.Windows.Forms.Button _btCancel; + private System.Windows.Forms.Button _btCategoryAdd; + private System.Windows.Forms.Button _btCategoryRemove; + private System.Windows.Forms.Button _btSave; + private System.Windows.Forms.Button _btTorrentClientAdd; + private System.Windows.Forms.Button _btTorrentClientDelete; + private System.Windows.Forms.Button _CategoriesBtSelectFolder; + private System.Windows.Forms.ComboBox _CategoriesCbStartCountSeeders; + private System.Windows.Forms.ComboBox _CategoriesCbTorrentClient; + private System.Windows.Forms.TextBox _CategoriesTbCategoryID; + private System.Windows.Forms.TextBox _CategoriesTbFolderDownloads; + private System.Windows.Forms.TextBox _CategoriesTbFullName; + private System.Windows.Forms.TextBox _CategoriesTbLabel; + private System.Windows.Forms.CheckBox _cbIsSaveTorrentFile; + private System.Windows.Forms.CheckBox _cbIsSaveWebPage; + private System.Windows.Forms.ComboBox _cbSubFolder; + private System.Windows.Forms.CheckBox _dbLoadInMemoryCheckbox; + private System.Windows.Forms.TabPage _tpAllCategories; + private System.Windows.Forms.TabPage _tpCategories; + private System.Windows.Forms.ComboBox apiHosts; + private System.Windows.Forms.TextBox categoryReportTemplate; + private System.Windows.Forms.CheckBox closeProgramCopies; + private System.Windows.Forms.CheckBox closeToTray; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnCategoryCategoryID; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnCategoryName; + private System.Windows.Forms.Label connectionCheck; + private System.Windows.Forms.DataGridView dgwCategories; + private System.Windows.Forms.DataGridView dgwTorrentClients; + private System.Windows.Forms.CheckBox DisableCertVerifyCheck; + private System.Windows.Forms.DataGridViewTextBoxColumn FolderName; + private TLO.Forms.ForumPages forumPages1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox10; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.GroupBox groupBox8; + private System.Windows.Forms.GroupBox groupBox9; + private System.Windows.Forms.CheckBox hideToTray; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.Label label21; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.Label label23; + private System.Windows.Forms.Label label24; + private System.Windows.Forms.Label label25; + private System.Windows.Forms.Label label26; + private System.Windows.Forms.Label label27; + private System.Windows.Forms.Label label28; + private System.Windows.Forms.Label label29; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label30; + private System.Windows.Forms.Label label31; + private System.Windows.Forms.Label label32; + private System.Windows.Forms.Label label33; + private System.Windows.Forms.Label label34; + private System.Windows.Forms.Label label35; + private System.Windows.Forms.Label label36; + private System.Windows.Forms.Label label37; + private System.Windows.Forms.Label label38; + private System.Windows.Forms.Label label39; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label40; + private System.Windows.Forms.Label label41; + private System.Windows.Forms.Label label42; + private System.Windows.Forms.Label label43; + private System.Windows.Forms.Label label44; + private System.Windows.Forms.Label label45; + private System.Windows.Forms.Label label46; + private System.Windows.Forms.Label label47; + private System.Windows.Forms.Label label48; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Button ProxyAddButton; + private System.Windows.Forms.TextBox proxyInput; + private System.Windows.Forms.ListBox ProxyListBox; + private System.Windows.Forms.TextBox reportHeaderTemplate; + private System.Windows.Forms.TextBox rutrackerHost; + private System.Windows.Forms.CheckBox showNotificationInTray; + private System.Windows.Forms.CheckBox showTrayIcon; + private System.Windows.Forms.TextBox summaryReportTemplate; + private System.Windows.Forms.CheckBox SystemProxy; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.TabPage tbpTorrentClients; + private System.Windows.Forms.TabPage templatesTabPage3; + private System.Windows.Forms.DataGridViewTextBoxColumn TorrentClientHost; + private System.Windows.Forms.DataGridViewTextBoxColumn TorrentClientPassword; + private System.Windows.Forms.DataGridViewTextBoxColumn TorrentClientPort; + private System.Windows.Forms.DataGridViewButtonColumn TorrentClientRemove; + private System.Windows.Forms.DataGridViewTextBoxColumn TorrentClientStatus; + private System.Windows.Forms.DataGridViewComboBoxColumn TorrentClientType; + private System.Windows.Forms.DataGridViewTextBoxColumn TorrentClientUsername; + private System.Windows.Forms.DataGridViewTextBoxColumn UID; + private System.Windows.Forms.CheckBox useProxyCheckBox; + + #endregion } -} \ No newline at end of file +} diff --git a/TLO/Forms/SettingsForm.cs b/TLO/Forms/SettingsForm.cs new file mode 100644 index 0000000..18d0e17 --- /dev/null +++ b/TLO/Forms/SettingsForm.cs @@ -0,0 +1,671 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Threading; +using System.Windows.Forms; +using NLog; +using TLO.Clients; +using TLO.Info; + +namespace TLO.Forms +{ + internal sealed partial class SettingsForm : Form + { + private readonly BindingSource _categoriesSource; + private readonly BindingSource _torrentClientsSource; + private BindingSource _proxyListSource; + + public SettingsForm() + { + InitializeComponent(); + var current = Settings.Current; + dgwTorrentClients.AutoGenerateColumns = false; + dgwTorrentClients.ClearSelection(); + dgwTorrentClients.DataSource = null; + _torrentClientsSource = new BindingSource {DataSource = ClientLocalDb.Current.GetTorrentClients()}; + dgwTorrentClients.DataSource = _torrentClientsSource; + dgwTorrentClients.CellClick += (sender, args) => + { + if (args.ColumnIndex == 8) + { + ClickButtons(dgwTorrentClients.CurrentCell, args); + } + }; + var neededRows = new List(); + var paintedRows = new List(); + var paintedValues = new List(); + + void CheckTorrentVersion(int row) + { + dgwTorrentClients.BeginInvoke(new Action(() => + { + new Thread(o => + { + var info = _torrentClientsSource[row] as TorrentClientInfo; + try + { + var client = info.Create(); + if (client.Ping()) + { + + lock (neededRows) + { + neededRows.Add(row); + paintedValues.Insert(row, "Работает"); + dgwTorrentClients.Rows[row].Cells[7].Style.BackColor = Color.Green; + dgwTorrentClients.Rows[row].Cells[7].Value = "Работает"; + } + } + else + { + lock (neededRows) + { + neededRows.Add(row); + paintedValues.Insert(row, "Нет связи"); + dgwTorrentClients.Rows[row].Cells[7].Style.BackColor = Color.Orange; + dgwTorrentClients.Rows[row].Cells[7].Value = "Нет связи"; + } + } + } + catch + { + lock (neededRows) + { + neededRows.Add(row); + paintedValues.Insert(row, "Ошибка"); + dgwTorrentClients.Rows[row].Cells[7].Style.BackColor = Color.Red; + dgwTorrentClients.Rows[row].Cells[7].Value = "Ошибка"; + } + } + } + ).Start(); + })); + } + + dgwTorrentClients.CellValueNeeded += (sender, args) => + { + if (args.ColumnIndex == 6) + { + args.Value = "******"; + } + + if (args.ColumnIndex == 7) + { + lock (neededRows) + { + if (!neededRows.Contains(args.RowIndex)) + { + args.Value = "Проверка..."; + CheckTorrentVersion(args.RowIndex); + } + else if (!paintedRows.Contains(args.RowIndex)) + { + args.Value = "Проверка..."; + paintedRows.Add(args.RowIndex); + } + else + { + paintedRows.Remove(args.RowIndex); + neededRows.Remove(args.RowIndex); + args.Value = paintedValues[args.RowIndex]; + } + } + } + }; + + dgwTorrentClients.CellValueChanged += (sender, args) => + { + if (args.ColumnIndex != 7) + { + CheckTorrentVersion(args.RowIndex); + } + }; + dgwTorrentClients.EditingControlShowing += (sender, args) => + { + if (!(args.Control is TextBox ctrl)) return; + ctrl.UseSystemPasswordChar = false; + if (dgwTorrentClients.CurrentCell.ColumnIndex != 6) return; + + ctrl.TextChanged += (sender2, args2) => + { + var info = _torrentClientsSource[dgwTorrentClients.CurrentRow.Index] as TorrentClientInfo; + info.UserPassword = ctrl.Text; + }; + ctrl.UseSystemPasswordChar = true; + }; + TorrentClientType.DataSource = new BindingSource + { + DataSource = new List + { + UTorrentClient.ClientId, + TransmissionClient.ClientId, + QBitTorrentClient.ClientId, + TixatiClient.ClientId, + } + }; + + dgwCategories.AutoGenerateColumns = false; + dgwCategories.ClearSelection(); + dgwCategories.DataSource = null; + _categoriesSource = new BindingSource {DataSource = ClientLocalDb.Current.GetCategoriesEnable()}; + dgwCategories.DataSource = _categoriesSource; + if (_categoriesSource.Count > 0) _categoriesSource.Position = 0; + if (_torrentClientsSource.Count > 0) _torrentClientsSource.Position = 0; + forumPages1.LoadSettings(); + CreatePageAllCategories(); + _appKeeperName.Text = current.KeeperName; + _appKeeperPass.Text = current.KeeperPass; + _appIsUpdateStatistics.Checked = current.IsUpdateStatistics; + _appCountDaysKeepHistory.Value = current.CountDaysKeepHistory; + _appPeriodRunAndStopTorrents.Value = current.PeriodRunAndStopTorrents; + _appCountSeedersReport.Value = current.CountSeedersReport; + _appIsAvgCountSeeders.Checked = current.IsAvgCountSeeders; + _appSelectLessOrEqual.Checked = current.IsSelectLessOrEqual; + { + CheckState checkState; + if (Settings.Current.LoadDBInMemory == null) + checkState = CheckState.Indeterminate; + else if (current.LoadDBInMemory != null && (bool) current.LoadDBInMemory) + checkState = CheckState.Checked; + else + checkState = CheckState.Unchecked; + + _dbLoadInMemoryCheckbox.AutoSize = true; + _dbLoadInMemoryCheckbox.Checked = current.LoadDBInMemory.GetValueOrDefault(false); + _dbLoadInMemoryCheckbox.CheckState = checkState; + } + closeProgramCopies.CheckState = current.DontRunCopy ? CheckState.Checked : CheckState.Unchecked; + DisableCertVerifyCheck.Checked = current.DisableServerCertVerify.GetValueOrDefault(false); + DisableCertVerifyCheck.CheckState = current.DisableServerCertVerify.GetValueOrDefault(false) + ? CheckState.Checked + : CheckState.Unchecked; + if (current.ApiHost != "") + foreach (string item in apiHosts.Items) + if (item == current.ApiHost) + apiHosts.SelectedItem = item; + rutrackerHost.Text = current.HostRuTrackerOrg; + + var appLogLevel = _appLogLevel; + var logLevel = current.LogLevel; + int num1; + if (!logLevel.HasValue) + { + num1 = 0; + } + else + { + logLevel = current.LogLevel; + num1 = logLevel.Value; + } + + decimal num2 = num1; + appLogLevel.Value = num2; + _appIsNotSaveStatistics.Checked = current.IsNotSaveStatistics; + _appReportTop1.Text = current.ReportTop1; + _appReportTop2.Text = current.ReportTop2; + _appReportLine.Text = current.ReportLine; + _appReportBottom.Text = current.ReportBottom; + summaryReportTemplate.Text = current.ReportSummaryTemplate; + categoryReportTemplate.Text = current.ReportCategoriesTemplate; + reportHeaderTemplate.Text = current.ReportCategoryHeaderTemplate; + _proxyListSource = new BindingSource {DataSource = current.ProxyList}; + ProxyListBox.DataSource = _proxyListSource; + ProxyListBox.SelectedItem = current.SelectedProxy; + if (current.UseProxy == true) + { + useProxyCheckBox.CheckState = CheckState.Checked; + if (current.SystemProxy == true) + { + SystemProxy.CheckState = CheckState.Checked; + } + } + else + { + useProxyCheckBox.CheckState = CheckState.Unchecked; + } + + ProxyAddButton.Click += (sender, args) => { _proxyListSource.Add(proxyInput.Text); }; + useProxyCheckBox.CheckStateChanged += (sender, args) => ProxySettingsSync(); + SystemProxy.CheckStateChanged += (sender, args) => ProxySettingsSync(); + ProxyListBox.SelectedValueChanged += (sender, args) => ProxySettingsSync(); + ProxySettingsSync(); + } + + public new Point Location + { + get => base.Location; + set + { + if ( + value.X > 0 && + value.Y > 0 && + value.X < SystemInformation.VirtualScreen.Size.Width - 100 && + value.Y < SystemInformation.VirtualScreen.Size.Height - 100 + ) + base.Location = value; + } + } + + private void _Focus_Enter(object sender, EventArgs e) + { + if (_categoriesSource.Current == null) + return; + var current1 = _categoriesSource.Current as Category; + if (sender == _CategoriesCbTorrentClient) + { + var selectedItem = _CategoriesCbTorrentClient.SelectedItem as TorrentClientInfo; + if (selectedItem == null) + return; + current1.TorrentClientUID = selectedItem.UID; + } + else if (sender == _CategoriesCbStartCountSeeders) + { + var result = 0; + if (!int.TryParse(_CategoriesCbStartCountSeeders.SelectedItem as string, out result)) + return; + current1.CountSeeders = result; + } + else if (sender == _CategoriesTbFolderDownloads) + { + current1.Folder = _CategoriesTbFolderDownloads.Text; + } + else if (sender == _cbIsSaveTorrentFile) + { + current1.IsSaveTorrentFiles = _cbIsSaveTorrentFile.Checked; + } + else if (sender == _cbIsSaveWebPage) + { + current1.IsSaveWebPage = _cbIsSaveWebPage.Checked; + } + else if (sender == _cbSubFolder) + { + var selectedItem = _cbSubFolder.SelectedItem as string; + if (string.IsNullOrWhiteSpace(selectedItem)) + return; + if (selectedItem != "Не нужен") + { + if (selectedItem != "С ID топика") + { + if (selectedItem != "Запрашивать") + return; + current1.CreateSubFolder = 2; + } + else + { + current1.CreateSubFolder = 1; + } + } + else + { + current1.CreateSubFolder = 0; + } + } + else + { + if (sender != _CategoriesTbLabel) + return; + current1.Label = string.IsNullOrWhiteSpace(_CategoriesTbLabel.Text) + ? current1.FullName + : _CategoriesTbLabel.Text.Trim(); + } + } + + private void SelectionChanged(object sender, EventArgs e) + { + if (sender == dgwTorrentClients) + { + if (_torrentClientsSource.Current != null) + { + var current = _torrentClientsSource.Current as TorrentClientInfo; + } + } + + if (sender == dgwCategories) + { + if (_categoriesSource.Current == null) + { + _CategoriesTbCategoryID.Text = string.Empty; + _CategoriesTbFullName.Text = string.Empty; + _CategoriesCbStartCountSeeders.Enabled = false; + _CategoriesTbLabel.Text = string.Empty; + } + else + { + var obj = _categoriesSource.Current as Category; + _CategoriesTbCategoryID.Text = obj.CategoryID.ToString(); + _CategoriesTbFullName.Text = obj.FullName; + _CategoriesCbStartCountSeeders.Enabled = true; + var startCountSeeders = _CategoriesCbStartCountSeeders; + int num; + string str; + if (obj.CountSeeders < 0) + { + str = "-"; + } + else + { + num = obj.CountSeeders; + str = num.ToString(); + } + + startCountSeeders.SelectedItem = str; + _CategoriesTbFolderDownloads.Text = obj.Folder; + _CategoriesCbTorrentClient.DataSource = null; + _CategoriesCbTorrentClient.DataSource = _torrentClientsSource.DataSource; + _CategoriesCbTorrentClient.SelectedItem = + (_CategoriesCbTorrentClient.DataSource as List) + .Where(x => x.UID == obj.TorrentClientUID) + .FirstOrDefault(); + num = obj.CreateSubFolder; + switch (num) + { + case 0: + _cbSubFolder.SelectedItem = "Не нужен"; + break; + case 1: + _cbSubFolder.SelectedItem = "С ID топика"; + break; + case 2: + _cbSubFolder.SelectedItem = "Запрашивать"; + break; + } + + _cbIsSaveWebPage.Checked = obj.IsSaveWebPage; + _cbIsSaveTorrentFile.Checked = obj.IsSaveTorrentFiles; + _CategoriesTbLabel.Text = string.IsNullOrWhiteSpace(obj.Label) ? obj.FullName : obj.Label; + } + } + + if (sender != _appIsNotSaveStatistics) + return; + if (_appIsNotSaveStatistics.Checked) + { + _appIsUpdateStatistics.Checked = false; + _appIsUpdateStatistics.Enabled = false; + } + else + { + _appIsUpdateStatistics.Enabled = true; + } + } + + private void ClickButtons(object sender, EventArgs e) + { + Cursor.Current = Cursors.WaitCursor; + if (sender == _btTorrentClientAdd) + { + _torrentClientsSource.Add(new TorrentClientInfo()); + _torrentClientsSource.Position = _torrentClientsSource.Count; + } + else if (sender == _btTorrentClientDelete || sender is DataGridViewButtonCell) + { + if (_torrentClientsSource.Current == null) return; + var current = _torrentClientsSource.Current as TorrentClientInfo; + if (MessageBox.Show($"Вы хотите удалить из списка torrent-клиент \"${current.Name}\"?", + "Запрос подтверждения", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == + DialogResult.Yes) + { + _torrentClientsSource.Remove(current); + } + } + + if (sender == _btCategoryAdd) + { + var dialog = new SelectCategory(); + dialog.Read(); + if (dialog.ShowDialog() == DialogResult.OK) + { + if (dialog.SelectedCategories.Count() > 0) + { + dialog.SelectedCategories.ForEach(x => + { + x.IsEnable = true; + _categoriesSource.Add(x); + }); + _categoriesSource.Position = _categoriesSource.Count; + } + + if (dialog.SelectedCategory == null) + return; + foreach (var cat in dialog.SelectedCategory) + { + if ((_categoriesSource.DataSource as List).Any( + x => x.CategoryID == cat.CategoryID)) + { + // var num = (int) MessageBox.Show("Выбранная категория уже присутствует"); + } + else + { + cat.IsEnable = true; + _categoriesSource.Add(cat); + _categoriesSource.Position = _categoriesSource.Count; + } + } + } + } + else if (sender == _btCategoryRemove) + { + if (_categoriesSource.Current == null) + return; + var current = _categoriesSource.Current as Category; + if (MessageBox.Show("Удалить из обработки раздел \"" + current.Name + "\"?", "Подтверждение", + MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes) + _categoriesSource.Remove(current); + } + else if (sender == _CategoriesBtSelectFolder) + { + if (_categoriesSource.Current == null) + return; + var current = _categoriesSource.Current as Category; + var folderBrowserDialog = new FolderBrowserDialog(); + folderBrowserDialog.SelectedPath = + string.IsNullOrWhiteSpace(current.Folder) ? "c:\\" : current.Folder; + if (folderBrowserDialog.ShowDialog() == DialogResult.OK) + { + current.Folder = folderBrowserDialog.SelectedPath; + _CategoriesTbFolderDownloads.Text = current.Folder; + } + } + + + if (sender == _btSave) + { + ClientLocalDb.Current.SaveTorrentClients(_torrentClientsSource.DataSource as List, + true); + ClientLocalDb.Current.CategoriesSave(_categoriesSource.DataSource as List); + forumPages1.Save(); + DialogResult = DialogResult.OK; + var current = setSettings(); + current.Save(); + ClientLocalDb.Current.Reconnect(); + Close(); + } + else if (sender == _btCancel) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } + + private Settings setSettings() + { + var current = Settings.Current; + current.KeeperName = _appKeeperName.Text; + current.KeeperPass = _appKeeperPass.Text; + current.IsUpdateStatistics = _appIsUpdateStatistics.Checked; + current.CountDaysKeepHistory = (int) _appCountDaysKeepHistory.Value; + current.PeriodRunAndStopTorrents = (int) _appPeriodRunAndStopTorrents.Value; + current.CountSeedersReport = (int) _appCountSeedersReport.Value; + current.IsAvgCountSeeders = _appIsAvgCountSeeders.Checked; + current.IsSelectLessOrEqual = _appSelectLessOrEqual.Checked; + current.LogLevel = (int) _appLogLevel.Value; + current.IsNotSaveStatistics = _appIsNotSaveStatistics.Checked; + current.ReportTop1 = _appReportTop1.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportTop2 = _appReportTop2.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportLine = _appReportLine.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportBottom = _appReportBottom.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportCategoryHeaderTemplate = + reportHeaderTemplate.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportCategoriesTemplate = + categoryReportTemplate.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + current.ReportSummaryTemplate = + summaryReportTemplate.Text.Replace("\n", "\r\n").Replace("\r\r", "\r"); + if (_dbLoadInMemoryCheckbox.CheckState != CheckState.Indeterminate) + current.LoadDBInMemory = _dbLoadInMemoryCheckbox.Checked; + current.DontRunCopy = closeProgramCopies.Checked; + current.UseProxy = useProxyCheckBox.Checked; + current.SystemProxy = SystemProxy.Checked; + current.SelectedProxy = ProxyListBox.SelectedItem?.ToString(); + current.ProxyList.Clear(); + foreach (var item in ProxyListBox.Items) + { + current.ProxyList.Add((string) item); + } + + current.DisableServerCertVerify = DisableCertVerifyCheck.Checked; + current.ApiHost = apiHosts.SelectedItem?.ToString(); + current.HostRuTrackerOrg = rutrackerHost.Text; + return current; + } + + private void CreatePageAllCategories() + { + Control control = panel2; + var dictionary1 = ClientLocalDb.Current.GetCategories().ToDictionary(x => x.CategoryID, x => x); + var categoriesEnable = ClientLocalDb.Current.GetCategoriesEnable().ToDictionary(x => x.CategoryID, x => x); + categoriesEnable.ToDictionary(x => x.Key, x => x.Value.ParentID); + for (var index = 0; index < 3; ++index) + foreach (var category in categoriesEnable.Values.ToArray()) + if (!categoriesEnable.ContainsKey(category.ParentID) && dictionary1.ContainsKey(category.ParentID)) + categoriesEnable.Add(dictionary1[category.ParentID].CategoryID, dictionary1[category.ParentID]); + + for (var index = 0; index < 3; ++index) + { + var list = dictionary1.Values.ToList(); + foreach (var category1 in categoriesEnable.Values.ToList()) + { + var c = category1; + foreach (var category2 in list + .Where(x => !categoriesEnable.ContainsKey(x.CategoryID) && x.ParentID == c.CategoryID) + .ToArray()) + if (!categoriesEnable.ContainsKey(category2.CategoryID) && + dictionary1.ContainsKey(category2.CategoryID)) + categoriesEnable.Add(category2.CategoryID, category2); + } + } + + var dictionary2 = ClientLocalDb.Current.GetReports(new int?()) + .Where(x => x.Key.Item2 == 0 && (uint) x.Key.Item1 > 0U) + .ToDictionary(x => x.Key.Item1, x => x.Value.Item1); + var num = 0; + var y1 = 10; + foreach (var category in categoriesEnable.Values.OrderBy(x => x.FullName)) + { + var label1Local = new Label(); + label1Local.AutoSize = true; + label1Local.Location = new Point(3, y1); + label1Local.Size = new Size(35, 13); + label1Local.TabIndex = num; + label1Local.Text = category.FullName; + control.Controls.Add(label1Local); + var y2 = y1 + 16; + var label2Local = new Label(); + label2Local.Location = new Point(6, y2); + label2Local.Size = new Size(123, 20); + label2Local.Text = "Списки хранимого"; + control.Controls.Add(label2Local); + ++num; + var textBox = new TextBox(); + textBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + textBox.Location = new Point(135, y2); + textBox.Size = new Size(panel1.Size.Width - 135, 20); + textBox.TabIndex = num; + textBox.Text = !string.IsNullOrWhiteSpace(category.ReportList) || + !dictionary2.ContainsKey(category.CategoryID) + ? category.ReportList + : dictionary2[category.CategoryID]; + control.Controls.Add(textBox); + y1 = y2 + 26; + } + } + + private void FormLoaded(object sender, EventArgs eventArgs) + { + DataBindings.Add(new Binding("Location", Properties.Settings.Default, + "SettingsWindowLocation", true, DataSourceUpdateMode.OnPropertyChanged)); + DataBindings.Add(new Binding("Size", Properties.Settings.Default, + "SettingsWindowSize", true, DataSourceUpdateMode.OnPropertyChanged)); + } + + private void ProxySettingsSync() + { + setSettings(); + if (useProxyCheckBox.CheckState == CheckState.Checked) + { + SystemProxy.Enabled = true; + if (SystemProxy.CheckState != CheckState.Checked) + { + ProxyListBox.Enabled = true; + proxyInput.Enabled = true; + ProxyAddButton.Enabled = true; + } + else + { + ProxyListBox.Enabled = false; + proxyInput.Enabled = false; + ProxyAddButton.Enabled = false; + } + } + else + { + SystemProxy.Enabled = false; + ProxyListBox.Enabled = false; + proxyInput.Enabled = false; + ProxyAddButton.Enabled = false; + } + + connectionCheck.Text = "Состояние: ПРОВЕРЯЕМ..."; + connectionCheck.BackColor = Color.Orange; + new Thread(o => + { + try + { + var page = new TloWebClient(useProxyCheckBox.Checked) + .DownloadString(string.Format( + "https://{1}/forum/profile.php?mode=viewprofile&u={0}", + Settings.Current.KeeperName, + Settings.Current.HostRuTrackerOrg + )).Replace("", ""); + if (!page.ToLower().Contains(Settings.Current.KeeperName.ToLower())) + { + connectionCheck.Invoke(new Action(() => + { + connectionCheck.Text = "Состояние: ПЛОХОЙ ОТВЕТ"; + connectionCheck.BackColor = Color.Red; + })); + } + else + { + connectionCheck.Invoke(new Action(() => + { + connectionCheck.Text = "Состояние: РАБОТАЕТ"; + connectionCheck.BackColor = Color.Green; + })); + } + } + catch (Exception e) + { + LogManager.GetLogger("ConnectionCheck").Trace(e.Message); + if (e.InnerException != null) + LogManager.GetLogger("ConnectionCheck").Trace(e.InnerException.Message); + connectionCheck.Invoke(new Action(() => + { + connectionCheck.Text = "Состояние: ОШИБКА"; + connectionCheck.BackColor = Color.Red; + })); + } + }).Start(); + } + } +} \ No newline at end of file diff --git a/TLO/Forms/SettingsForm.resx b/TLO/Forms/SettingsForm.resx new file mode 100644 index 0000000..4058f2b --- /dev/null +++ b/TLO/Forms/SettingsForm.resx @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAObk5ACjn6AEgn5/EY6Ki1SYl5dGe317AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANfU1AKTj5AeXVtbT0pISI1EQUPGTUpL7GZjYq5lZWIKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv4 + +QC9u7sEoJ6fDnN0dhJzdXk0aGhqc29qa9hKR0j1Yl9g/X15ev+JhIT/WVVT7FxcWDb6//sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5uXlAZua + mwiNjIwfcm9zU1pYW5Jyb3DITExP1FBPU+1paGr6ko2O/paRkv+alJX/l5GS/4aBgf9QTUr7T09Kj35+ + fQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz9/AC7u7sEkpGUEYaE + hTdkZWdvU1NWrkdHSd9KSk72Wlhc/YaBgv+Lhoj/lpCR/5uVlf+YkpP/jYeI/3t1df9iXlz/ZWBh/0hD + Qv48ODjvT0xMTn17ewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJAJWSlAeRj5Afd3R2UVla + XY5HSU3JNzk87k1OUPpxb3L+jIiL/5uWmP+emJn/n5mZ/5mSk/+LhYb/eHNy/2ZgYP9XUVD/RkE//0Q/ + Pf9dWFj/Uk5O/0I9PP5IRUWtZ2VlCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfnJ4WVVNWnkhJ + S95PUFP1ZWVo/Xx4e/+FgYP/mpOW/6Gbm/+gmpv/m5SV/4B6e/9vaGj/VE1N/1dQUP90cHD/RD49/y0n + Jv8kIB//MSwr/zk0M/9XU1P/SUVD/0pGRexWVFQ7k5OTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSg + oz55dXfyi4eK/56am/+inZ7/oJqb/5mTlP+Nhoj/c21u/2ZhYf9lXl//WlRU/3Jyc/9dWVj/RUA+/3Fs + bP9NSEj/Ih0c/x0YF/8dGBj/IBsa/y0oJ/9LRUT/RD8//URBQZdjY2EGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAApqSlXp6ZmveblZb/lI2O/4R9fv9zbW3/c3Bx/6Ggov9RUlT/ODc4/1VTVP9NS03/Z2lt/3Jw + cf9bVFL/VU9P/zw3OP8eGRn/GRUU/x0bI/8jICj/My0s/1VOTf9KRUT/QT085FJRUCsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKh4iLcWxs/G1nZ/9WUE//V09P/0xHR/94dXz/w8jQ/73DzP+vtr3/t7/I/2Jl + av8oKCr/IB4f/0pERP9GQD//JyYr/yUjI/8jISD/KSYu/z86Pv9RS0j/WVJR/1BKSv9CPj37Q0BAg2Vl + ZAMAAAAAAAAAAAAAAAAAAAAAAAAAAHFubm5jXl70c21u/3FsbP9STkz/WFVW/5+hqP/K0tz/0dnj/9Ha + 4//M1d//maCp/z5ASf8YFhf/JCAg/zczMv82Mzb/OTU0/0Q+Pv9BOzr/SUJC/09HR/9VTk7/U05N/0ZB + QP4/PDvaWVhXIAAAAAAAAAAAAAAAAAAAAAAAAAAAjoqKDHBqaqs3MzP9YFxd/zs2Nf94dnn/ztbf/8rT + 3P/Q2eL/ztbf/7G3vv+MkJj/PD5G/xcWGP8WFRj/HB4r/y80Tf9AOjn/Pzo5/z45OP8/Ojn/Qz49/0ZB + QP9KRUX/SENC/z87OvlLSUhye3l5AgAAAAAAAAAAAAAAAAAAAACtq6oAgHt6Oj04OOgkHx//NTEw/5me + ov/R2eH/vsbP/8rT3P98foP/c25x/3d2e/9GUF3/ISIv/xwhMv8kLUv/Iic1/yMhIv8eGxz/Gxka/xkY + GP8bGBj/Ih4f/zAsLP9DPj7/RUA//k1KScxsamkXAAAAAAAAAAAAAAAAAAAAAAAAAACVj48FaGJiiyAb + HPshHh7/oaWq/9be5v/P1+D/wsrT/2tpbP+0s7b/yMjJ/7e6vf+MlKP/TVZn/z1FT/8xQE3/L0FS/yM0 + RP8gLDj/FBkh/wwND/8TEBD/FRIS/yAcHP9EPz7/SUVE9lNSUV+Ji4oAAAAAAAAAAAAAAAAAAAAAAAAA + AACEgIAjR0JD1hMREf56fYH/1d7n/9Xe5//L1N3/k5Wa/7q5u/+4t7r/7u7v/+Lh4/+Aj5z/iZmo/1l+ + oP8/g8D/OIPE/zV8u/8vbaj/JFSC/xs1T/8SFh7/GhcX/0I9Pf9GQkH+SEZFvGloaA8AAAAAAAAAAAAA + AAAAAAAAAAAAAJ6cnAJybW1sKCMj901OUf/T2+L/ztfg/8vU3f+wt7//R0xR/3SWr/+m0e3/r9Xt/7PG + 0v+Pnqn/xszQ/3qOo/9GgLT/OITH/zOAxP8yer//MHS5/ytim/8zQ1n/Uk9P/1xXV/9GQkHyWldXTYWE + hAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGMjBNMSEi+JSQk/oKEh//L0tn/zNXd/6Ottv9diqr/bbbo/2e0 + 6f9hr+f/Y67l/3u24v+ZxOP/scTR/5mnsf9mk7v/OYLF/zN+wv8xeb7/L3W7/zBtrf86VnX/Q0JE/05K + Sv5QTk6saGZmCQAAAAAAAAAAAAAAAAAAAAAAAAAAm5eWAHBsbEw4MzTvDg4O/0BAQv9ucXX/cZav/3m9 + 7f9zu+7/bLfr/2Wy6f9creb/Vafi/1Ch3v9UoNr/YKLX/3Gl0f9hkr//PoTD/zJ9wf8xeL7/L3S6/y5w + s/81VXj/VlVX/2RiY+1hYGA9pqenAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIiICWJeXaAgHR39RkFC/zAw + M/9Scon/aaDF/3Gz4P9vt+n/arbr/2Ox6f9ereX/YKDQ/2+fxf9PfKL/OG6e/0CFwv89icv/NIHG/zF9 + wf8xeL3/L3S6/y1wsf9AVGv/cnBx/VtZWZp+fX0GAAAAAAAAAAAAAAAAAAAAAAAAAAC0tLQAe3h4MFhU + VOFoY2P+ZGdr/1VkcP9FVWL/PlNj/0dke/9bkrv/aLLn/2qcw/9/pcn/XYu7/1OEuP86Xob/J0hq/zd6 + tv84hsv/NIHG/zJ9wv8weL//Lna8/zJnnf9UVVj/WlhY5nd3dy/Y2NgAAAAAAAAAAAAAAAAAAAAAAAAA + AACSj5AEbGdoflNQUPlnhJj/icXt/4PB6f96uOL/cq3V/22t2P9rsOL/RH21/1+Pw/+brcr/k6vP/4Wh + xP9Oh8D/O2+g/z2Lz/84hsv/NIHI/zB8xf8ueML/LnO4/0JMWv9dWVn7bGlqiYyLiwQAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACDf38cYVxbzWWCl/6LyfH/iMnx/4PG8f9+wvD/dr/u/2ew5f9RjMn/hpi8/8jA + 1f+xsLj/srnV/3efyf9Rk9D/QZHT/zuL0P82hs3/M4HJ/zB8xv8ud77/Okpc/0lGRf52cnLcnp2dHwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6OjgFsaWheVmRw9IfC6v+LyvL/h8fx/4HE8f98wfD/cbnr/0uN + zf9dib3/oJ3E/7m92P+esc7/Y5rR/06Z3P9Fldj/P5DU/zqL0f82hs3/M4HK/zB4vP85RU//ODUz/42K + jPixr7NkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIF/fg5TU1a0aZGt/YzJ8v+JyfL/hcby/4DD + 8f96v+//arHl/1SV0f9llsn/UojD/2ye0P9Qmdv/Tp3e/0ma2/9ElNf/Po/T/zqK0P82hc7/M2uf/zw7 + Pf8/Ozr/iYaK/a6ssZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnJaXAGpoaUJCSVHrdaXH/4rJ + 8v+Jx/P/hMXy/37C8f95vu//cbns/2av5v9eqeL/XKnj/1io5P9SouH/TZ3e/0iY2/9Ck9b/PY7S/zqC + wP85Slv/IyEg/yAdHf9ZVFf+paOmjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhoOEB1tY + WJY5Qkn8bZq4/4jH7/+Hx/L/gsTw/33B8P93vu7/cLns/2q26v9jsej/XKzm/1am4/9RoOD/S5vd/0WW + 2v9OlM//Umd//zIwMP8LCwr/HBka/0M+P/6CfoCPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC4tbUAfXt6JVlVVLUzNDf8WHuT/4TA5/+DxO3/gMPw/3vA8P90vO7/brjs/2i06v9gsOj/Wqvl/1ak + 4f9Xot7/danS/4GMmf9STU3+T0xN/S4rK/dGQkLpV1NT0mVhYX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACuq6oAfnx8PVVRUfEuLzD/KzlE/z1UZf9Ygp7/aqHG/3O24/9xuen/bLPl/2On + 1v9emcT/cpm6/pamtfyHh4n0W1dX4ldTU7psamqJa2hoVXdzdCp+fX0TgYCADgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBfn4YYl1dykA8O/4WExL/GBYW/yAfIP8kJir/KzxJ/zhR + Y/5MW2j6U1dd8VlZXNh2cXSseHR0e2ppaUl1dHMgcnBvC4+OjgOpp6cAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJqWlgFxbW1bVlFR9FBLS/8fHBz9JyUm9zQy + Mus9PDzLTUtLnWBcXGlwbW48dXNyF3Zycgihnp4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIaEhBBdWVq6Yl5fyWBc + XY5iYGFZcG9vLXp4dxCDgoIFtLGxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo6GjAoB/ + gVF+fX8ulZKSA7e1tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA///D///+Af//4AH//gAA//AAAP+AAAB/AAAAfwAAAD8AAAA/AAAAHwAA + AB8AAAAPgAAAD4AAAA/AAAAHwAAAB+AAAAPwAAAD8AAAAfgAAAH4AAAA/AAAAPwAAAD+AAAA/wAAAP8A + AAD/gAAA/8AAAP/AAA//wAD//+Af///h//8= + + + \ No newline at end of file diff --git a/TLO/Info/Category.cs b/TLO/Info/Category.cs new file mode 100644 index 0000000..b341300 --- /dev/null +++ b/TLO/Info/Category.cs @@ -0,0 +1,56 @@ +using System; + +namespace TLO.Info +{ + internal class Category + { + public Category() + { + LastUpdateTopics = new DateTime(2000, 1, 1); + LastUpdateStatus = new DateTime(2000, 1, 1); + CountSeeders = 2; + CreateSubFolder = 2; + } + + public int CategoryID { get; set; } + + public int ParentID { get; set; } + + public int OrderID { get; set; } + + public string Name { get; set; } + + public string FullName { get; set; } + + public bool IsEnable { get; set; } + + public int CountSeeders { get; set; } + + public Guid TorrentClientUID { get; set; } + + public int CreateSubFolder { get; set; } + + public string Folder { get; set; } + + public string Label { get; set; } + + public bool IsSaveTorrentFiles { get; set; } + + public string FolderTorrentFile { get; set; } + + public bool IsSaveWebPage { get; set; } + + public string FolderSavePageForum { get; set; } + + public string ReportList { get; set; } + + public DateTime LastUpdateTopics { get; set; } + + public DateTime LastUpdateStatus { get; set; } + + public override string ToString() + { + return FullName; + } + } +} \ No newline at end of file diff --git a/TLO/Info/TopicInfo.cs b/TLO/Info/TopicInfo.cs new file mode 100644 index 0000000..3106952 --- /dev/null +++ b/TLO/Info/TopicInfo.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Web; + +namespace TLO.Info +{ + internal class TopicInfo : ICloneable + { + public int TopicID { get; set; } + + public int Seeders { get; set; } + + public int Leechers { get; set; } + + public string Hash { get; set; } + + public int CategoryID { get; set; } + + public string Name => HttpUtility.HtmlDecode(Name2); + + public string Name2 { get; set; } + + public string Label { get; set; } + + public string TorrentName { get; set; } + + public List Files { get; set; } + + public int Status { get; set; } + + public long Size { get; set; } + + public DateTime RegTime { get; set; } + + public decimal? AvgSeeders { get; set; } + + public bool IsKeeper { get; set; } + + public bool IsKeep { get; set; } + + public bool IsDownload { get; set; } + + public bool IsBlackList { get; set; } + + public bool IsSelected { get; set; } + + public string Alternative => ">>>>"; + + public bool? IsRun { get; set; } + + public bool IsPause { get; set; } + + public bool[] TorrentClientStatus { get; set; } + + public decimal PercentComplite { get; set; } + + public bool Checked { get; set; } + + public string SizeToString => sizeToString(Size); + + public string StatusToString + { + get + { + switch (Status) + { + case 0: + return "*"; + case 1: + return "x"; + case 2: + return "√"; + case 3: + return "?"; + case 4: + return "!"; + case 5: + return "D"; + case 6: + return "©"; + case 7: + return "∑"; + case 8: + return "#"; + case 9: + return "%"; + case 10: + return "T"; + case 11: + return "∏"; + default: + return "-"; + } + } + } + + public string StatusToHtml + { + get + { + switch (Status) + { + case 0: + return "*"; + case 1: + return "x"; + case 2: + return "√"; + case 3: + return "?"; + case 4: + return "!"; + case 5: + return "D"; + case 6: + return "©"; + case 7: + return "∑"; + case 8: + return "#"; + case 9: + return "%"; + case 10: + return "T"; + case 11: + return "∏"; + default: + return "-"; + } + } + } + + public string RegTimeToString => RegTime.ToString("dd.MM.yyyy"); + + public int PosterID { get; set; } + + public bool IsPoster { get; set; } + + public int? KeeperCount { get; set; } + + public object Clone() + { + var ti = new TopicInfo(); + + foreach (var prop in Type.GetType("TLO.Info.TopicInfo").GetProperties()) + { + ti.CategoryID = CategoryID; + if (prop.CanWrite) prop.SetValue(ti, prop.GetValue(this)); + } + + return ti; + } + + public static string sizeToString(long size) + { + if (size >= new decimal(int.MinValue, 2, 0, false, 1)) + return Math.Round(size / new decimal(int.MinValue, 2, 0, false, 1), 2) + " GB"; + if (size >= new decimal(10485760, 0, 0, false, 1)) + return Math.Round(size / new decimal(10485760, 0, 0, false, 1), 2) + " MB"; + if (size >= new decimal(10240, 0, 0, false, 1)) + return Math.Round(size / new decimal(10240, 0, 0, false, 1), 2) + " KB"; + return Math.Round((decimal) size, 2) + " B"; + } + + // public override string ToString() + // { + // return $"[{Hash}]: {Name}"; + // } + } +} \ No newline at end of file diff --git a/TLO/Info/TorrentClientInfo.cs b/TLO/Info/TorrentClientInfo.cs new file mode 100644 index 0000000..5de7c4b --- /dev/null +++ b/TLO/Info/TorrentClientInfo.cs @@ -0,0 +1,55 @@ +using System; +using TLO.Clients; + +namespace TLO.Info +{ + internal class TorrentClientInfo + { + public TorrentClientInfo() + { + UID = Guid.NewGuid(); + Name = string.Empty; + Type = UTorrentClient.ClientId; + ServerName = string.Empty; + ServerPort = 8080; + UserName = string.Empty; + UserPassword = string.Empty; + LastReadHash = new DateTime(2000, 1, 1); + } + + public string Id { get; } + + public Guid UID { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public string ServerName { get; set; } + + public int ServerPort { get; set; } + + public string UserName { get; set; } + + public string UserPassword { get; set; } + + public DateTime LastReadHash { get; set; } + + public override string ToString() + { + return Name; + } + + public ITorrentClient Create() + { + return Type switch + { + UTorrentClient.ClientId => new UTorrentClient(ServerName, ServerPort, UserName, UserPassword), + TransmissionClient.ClientId => new TransmissionClient(ServerName, ServerPort, UserName, UserPassword), + QBitTorrentClient.ClientId => new QBitTorrentClient(ServerName, ServerPort, UserName, UserPassword), + TixatiClient.ClientId => new TixatiClient(ServerName, ServerPort, UserName, UserPassword), + _ => throw new NotSupportedException() + }; + } + } +} \ No newline at end of file diff --git a/TLO/Info/UserInfo.cs b/TLO/Info/UserInfo.cs new file mode 100644 index 0000000..e1a3e78 --- /dev/null +++ b/TLO/Info/UserInfo.cs @@ -0,0 +1,9 @@ +namespace TLO.Info +{ + internal class UserInfo + { + public int UserID { get; set; } + + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/TLO/Program.cs b/TLO/Program.cs new file mode 100644 index 0000000..a498542 --- /dev/null +++ b/TLO/Program.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Web; +using System.Windows.Forms; +using MihaZupan; +using TLO.Forms; + +namespace TLO +{ + internal static class Program + { + [DllImport("kernel32.dll")] + static extern bool AttachConsole(int dwProcessId); + private const int ATTACH_PARENT_PROCESS = -1; + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern int FreeConsole(); + [STAThread] + private static void Main() + { + AttachConsole(ATTACH_PARENT_PROCESS); + if (Settings.Current.DontRunCopy) + { + var currentProcess = Process.GetCurrentProcess(); + foreach (var process in Process.GetProcessesByName(currentProcess.ProcessName)) + { + if (process.Id == currentProcess.Id) continue; + process.CloseMainWindow(); + process.WaitForExit(2000); + process.Close(); + } + } + + if (Settings.Current.UseProxy == true) + { + if (Settings.Current.SystemProxy == true) + { + WebRequest.DefaultWebProxy = WebRequest.GetSystemWebProxy(); + } + else + { + var proxy = Settings.Current.SelectedProxy; + if (proxy.Contains("http://")) + { + WebRequest.DefaultWebProxy = new WebProxy(proxy); + } + else + { + var uri = new Uri(proxy); + WebRequest.DefaultWebProxy = new HttpToSocks5Proxy(uri.Host, uri.Port); + } + } + } + + try + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + var mainForm = new MainForm(); + new WindowTrayAssociation(mainForm).SyncSettings(); + Application.ApplicationExit += (sender, args) => TrayObject.TrayIcon.Dispose(); + Application.Run(mainForm); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); + } + FreeConsole(); + } + + + + public static List GetAllNodes(this TreeNode _self) + { + List result = new List(); + result.Add(_self); + foreach (TreeNode child in _self.Nodes) + { + result.AddRange(child.GetAllNodes()); + } + return result; + } + + public static bool IsRunningOnMono() + { + return Type.GetType("Mono.Runtime") != null; + } + } +} \ No newline at end of file diff --git a/TLO/Properties/AssemblyInfo.cs b/TLO/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7292bee --- /dev/null +++ b/TLO/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TLO")] +[assembly: AssemblyDescription("Torrents list organizer")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TLO")] +[assembly: AssemblyCopyright("Copyright © 2014-2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9b0990b0-a1dd-44ae-ab0c-0510e8769860")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.17.0")] +[assembly: AssemblyFileVersion("2.17.0")] \ No newline at end of file diff --git a/TLO/Properties/Resources.Designer.cs b/TLO/Properties/Resources.Designer.cs new file mode 100644 index 0000000..7181a5a --- /dev/null +++ b/TLO/Properties/Resources.Designer.cs @@ -0,0 +1,69 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TLO.Properties +{ + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", + "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", + "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState + .Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = + new global::System.Resources.ResourceManager("TLO.Properties.Resources", + typeof(Resources).Assembly); + resourceMan = temp; + } + + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState + .Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get { return resourceCulture; } + set { resourceCulture = value; } + } + } +} \ No newline at end of file diff --git a/Properties/Resources.resx b/TLO/Properties/Resources.resx similarity index 84% rename from Properties/Resources.resx rename to TLO/Properties/Resources.resx index 6ab4d89..ffecec8 100644 --- a/Properties/Resources.resx +++ b/TLO/Properties/Resources.resx @@ -1,124 +1,117 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\hdd.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/TLO/Properties/Settings.Designer.cs b/TLO/Properties/Settings.Designer.cs new file mode 100644 index 0000000..b8cc989 --- /dev/null +++ b/TLO/Properties/Settings.Designer.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TLO.Properties +{ + [global::System.Configuration.SettingsProvider(typeof(TLO.Tools.SettingsProvider))] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + private static Settings defaultInstance = + ((Settings) (global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get { return defaultInstance; } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0,0")] + public global::System.Drawing.Point WindowLocation { + get { + return ((global::System.Drawing.Point)(this["WindowLocation"])); + } + set { + this["WindowLocation"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0,0")] + public global::System.Drawing.Size WindowSize { + get { + return ((global::System.Drawing.Size)(this["WindowSize"])); + } + set { + this["WindowSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0,0")] + public global::System.Drawing.Point SettingsWindowLocation { + get { + return ((global::System.Drawing.Point)(this["SettingsWindowLocation"])); + } + set { + this["SettingsWindowLocation"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0,0")] + public global::System.Drawing.Size SettingsWindowSize { + get { + return ((global::System.Drawing.Size)(this["SettingsWindowSize"])); + } + set { + this["SettingsWindowSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool ShowInTray { + get { + return ((bool)(this["ShowInTray"])); + } + set { + this["ShowInTray"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool HideToTray { + get { + return ((bool)(this["HideToTray"])); + } + set { + this["HideToTray"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool CloseToTray { + get { + return ((bool)(this["CloseToTray"])); + } + set { + this["CloseToTray"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool NotificationInTray { + get { + return ((bool)(this["NotificationInTray"])); + } + set { + this["NotificationInTray"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool DontRunCopy { + get { + return ((bool)(this["DontRunCopy"])); + } + set { + this["DontRunCopy"] = value; + } + } + } +} \ No newline at end of file diff --git a/TLO/Properties/Settings.settings b/TLO/Properties/Settings.settings new file mode 100644 index 0000000..55bbddb --- /dev/null +++ b/TLO/Properties/Settings.settings @@ -0,0 +1,35 @@ + + + + + + + + 0, 0 + + + 0, 0 + + + 0, 0 + + + 0, 0 + + + False + + + False + + + False + + + False + + + True + + + diff --git a/TLO/Reports.cs b/TLO/Reports.cs new file mode 100644 index 0000000..5dc7331 --- /dev/null +++ b/TLO/Reports.cs @@ -0,0 +1,417 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using Stubble.Core; +using Stubble.Core.Builders; +using TLO.Clients; +using TLO.Info; + +namespace TLO +{ + internal static class Reports + { + private static StubbleVisitorRenderer _stubble; + + private static StubbleVisitorRenderer Stubble + { + get + { + if (_stubble != null) return _stubble; + + var stubble = new StubbleBuilder() + .Configure(settings => + { + settings.SetIgnoreCaseOnKeyLookup(true); + settings.SetMaxRecursionDepth(512); + }) + .Build(); + + return _stubble = stubble; + } + } + + public static void CreateReports() + { + ClientLocalDb.Current.ClearReports(); + + var categories = ClientLocalDb.Current.GetCategoriesEnable(); + var currReports = ClientLocalDb.Current.GetReports(new int?()); + var reports = new Dictionary>(); + var allStatistics = ClientLocalDb.Current + .GetStatisticsByAllUsers() + .Where(x => !string.IsNullOrWhiteSpace(x.Item2)) + .ToArray(); + + var statistics = allStatistics + .Where(x => x.Item2 == Settings.Current.KeeperName) + .ToArray(); + var catIds = categories.Select(x => x.CategoryID).ToArray(); + + var summaryTopicsAmount = statistics + .Where(x => catIds.Contains(x.Item1)) + .Sum(x => x.Item3); + var summaryTopicsSize = statistics + .Where(x => catIds.Contains(x.Item1)) + .Sum(x => x.Item4); + + var summaryReportTemplate = Settings.Current.ReportSummaryTemplate; + var categoriesList = new List(); + var summaryReportData = new Dictionary + { + {"today", DateTime.Now.ToString("dd.MM.yyyy")}, + {"summary_topics_count", summaryTopicsAmount}, + {"summary_topics_size", summaryTopicsSize.ToString("N")}, + {"categories", categoriesList} + }; + foreach (var category in categories.OrderBy(x => x.FullName)) + { + var st = + statistics.FirstOrDefault(x => x.Item1 == category.CategoryID) ?? + new Tuple(category.CategoryID, "<->", 0, decimal.Zero); + + if (!currReports.ContainsKey(new Tuple(st.Item1, 1))) continue; + + var url = currReports[new Tuple(st.Item1, 1)].Item1; + if (!string.IsNullOrWhiteSpace(url) && url.Split('=').Length > 2) + url = url.Split('=')[2]; + else + url = null; + + categoriesList.Add( + new Dictionary + { + { + "url", + url != null ? string.Format("https://rutracker.org/forum/viewtopic.php?p={0}#{0}", url) : "" + }, + {"category_name", category.FullName}, + {"topics_count", st.Item3}, + {"topics_size", st.Item4.ToString("N")} + } + ); + } + + var summaryReportRendered = Stubble.Render(summaryReportTemplate, summaryReportData); + + reports.Add(0, new Dictionary()); + reports[0].Add(0, summaryReportRendered); + + ClientLocalDb.Current.SaveReports(reports); + + reports.Clear(); + + var headerOfReportTemplate = Settings.Current.ReportCategoryHeaderTemplate; + + foreach (var category in categories) + { + var st = allStatistics.Where(x => x.Item1 == category.CategoryID && x.Item3 > 0 && x.Item2 != "All"); + var all = allStatistics.FirstOrDefault(x => x.Item1 == category.CategoryID && x.Item2 == "All"); + if (st.Count() != 0 && all != null) + { + var keepersList = new List(); + var reportHeader = new Dictionary + { + {"category_uri", "viewforum.php?f=" + category.CategoryID}, + {"category_name", category.Name}, + {"category_check_seeds_uri", "tracker.php?f=" + category.CategoryID + "&tm=-1&o=10&s=1"}, + {"today", DateTime.Now.ToString("dd.MM.yyyy")}, + {"topics_count", all.Item3}, + {"topics_size", all.Item4.ToString("N")}, + {"keepers_count", st.Count().ToString()}, + {"keep_topics_count", st.Sum(x => x.Item3).ToString()}, + {"keep_topics_size", st.Sum(x => x.Item4).ToString("N")}, + {"keepers", keepersList} + }; + + var num = 0; + foreach (var tuple2 in st.OrderBy(x => x.Item2)) + { + ++num; + keepersList.Add( + new Dictionary + { + {"keeper_number", num.ToString()}, + { + "keeper_profile_uri", + "profile.php?mode=viewprofile&u=" + + HttpUtility.UrlEncode(tuple2.Item2.Replace("", "").Trim()) + }, + {"keeper_username", tuple2.Item2.Replace("", "")}, + {"keep_topics_count", tuple2.Item3.ToString()}, + {"keep_topics_size", tuple2.Item4.ToString("N")} + } + ); + } + + var reportHeaderRendered = Stubble.Render(headerOfReportTemplate, reportHeader); + + reports.Add(category.CategoryID, new Dictionary()); + reports[category.CategoryID].Add(0, reportHeaderRendered); + } + } + + ClientLocalDb.Current.SaveReports(reports); + reports.Clear(); + var format1 = Settings.Current.ReportTop1.Replace("%%CreateDate%%", "{0}") + .Replace("%%CountTopics%%", "{1}").Replace("%%SizeTopics%%", "{2}") + "\r\n"; + var format2 = Settings.Current.ReportTop2.Replace("%%CreateDate%%", "{0}") + .Replace("%%CountTopics%%", "{1}").Replace("%%SizeTopics%%", "{2}") + .Replace("%%NumberTopicsFirst%%", "{3}").Replace("%%NumberTopicsLast%%", "{4}") + .Replace("%%ReportLines%%", "{5}").Replace("%%Top1%%", "{6}") + "\r\n"; + var format3 = Settings.Current.ReportLine.Replace("%%ID%%", "{0}").Replace("%%Name%%", "{1}") + .Replace("%%Size%%", "{2}").Replace("%%Status%%", "{3}").Replace("%%CountSeeders%%", "{4}") + .Replace("%%Date%%", "{5}"); + var num1 = 115000; + var stringBuilder2 = new StringBuilder(); + var stringBuilder3 = new StringBuilder(); + foreach (var category in categories) + { + var num2 = 0; + var num3 = 0; + var num4 = 1; + var key = 0; + stringBuilder2.Clear(); + stringBuilder3.Clear(); + var array3 = ClientLocalDb.Current.GetTopicsByCategory(category.CategoryID).Where( + x => + { + if (x.IsKeep && (x.Seeders <= Settings.Current.CountSeedersReport || + Settings.Current.CountSeedersReport == -1)) + return !x.IsBlackList; + return false; + }).OrderBy(x => x.Name2).ToArray(); + if (array3.Length != 0) + { + reports.Add(category.CategoryID, new Dictionary()); + var dictionary = reports[category.CategoryID]; + var str = string.Format(format1, DateTime.Now.ToString("dd.MM.yyyy"), + array3.Length, + TopicInfo.sizeToString( + array3.Sum(x => x.Size))); + foreach (var topicInfo in array3) + { + stringBuilder3.AppendLine(string.Format(format3, (object) topicInfo.TopicID, + (object) topicInfo.Name2, (object) topicInfo.SizeToString, + (object) topicInfo.StatusToHtml, (object) topicInfo.Seeders, + (object) topicInfo.RegTimeToString)); + ++num2; + ++num3; + if (num2 % 10 == 0 || array3.Length <= num2) + { + if (array3.Length == num2) + { + if (num3 == 0) + stringBuilder2.AppendFormat("[*={0}{1}", num4, + stringBuilder3.ToString().Substring(2)); + else + stringBuilder2.AppendLine(stringBuilder3.ToString()); + } + + if (num1 <= stringBuilder2.Length + stringBuilder3.Length + str.Length || + array3.Length <= num2) + { + ++key; + var num5 = num2 < array3.Length ? num2 - 10 : num2; + dictionary.Add(key, + string.Format(format2, DateTime.Now.ToString("dd.MM.yyyy"), + (object) array3.Length, + (object) TopicInfo.sizeToString( + array3.Sum( + x => x.Size)), (object) num4, (object) num5, + (object) stringBuilder2.ToString(), (object) str) + + Settings.Current.ReportBottom); + stringBuilder2.Clear(); + num3 = 0; + num4 = num5 + 1; + str = string.Empty; + } + + if (num3 == 0) + stringBuilder2.AppendFormat("[*={0}{1}\r\n", num4, + stringBuilder3.ToString().Substring(2)); + else + stringBuilder2.AppendLine(stringBuilder3.ToString()); + stringBuilder3.Clear(); + } + } + } + } + + ClientLocalDb.Current.SaveReports(reports); + } + + public static void CreateReportByRootCategories() + { + // TODO вынести запросы обратно в клиент + using (var command = ClientLocalDb.Current.CreateCommand()) + { + ClientLocalDb.Current.GetStatisticsByAllUsers(); + var reports = new Dictionary>(); + var source1 = + new Dictionary>(); + var dictionary1 = + new Dictionary, Tuple>(); + var dictionary2 = + new Dictionary, Tuple>(); + var tupleList = + new List>(); + command.CommandText = @" +SELECT c.CategoryID, c.FullName, SUM(Count)Count, SUM(Size)Size +FROM + ( + SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION + SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 + ) AS t + JOIN Category AS c ON (t.ParentID = c.CategoryID) + JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All') +GROUP BY + c.CategoryID, c.FullName +ORDER BY c.FullName"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + source1.Add(sqLiteDataReader.GetInt32(0), + new Tuple(sqLiteDataReader.GetString(1), + sqLiteDataReader.GetDecimal(2), sqLiteDataReader.GetDecimal(3))); + } + + command.CommandText = @" +SELECT c.CategoryID, c.FullName, k.KeeperName, SUM(Count)Count, SUM(Size)Size +FROM + ( + SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION + SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 + ) AS t + JOIN Category AS c ON (t.ParentID = c.CategoryID) + JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All') +GROUP BY + c.CategoryID, c.FullName, k.KeeperName +ORDER BY c.FullName, k.KeeperName"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + dictionary1.Add( + new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetString(2)), + new Tuple(sqLiteDataReader.GetString(1), + sqLiteDataReader.GetDecimal(3), sqLiteDataReader.GetDecimal(4))); + } + + command.CommandText = @" +SELECT t.ParentID, c.CategoryID, c.FullName, k.KeeperName, SUM(Count)Count, SUM(Size)Size +FROM + ( + SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION + SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 + ) AS t + JOIN Category AS c ON (t.CategoryID = c.CategoryID) + JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All') +GROUP BY + t.ParentID, c.FullName, k.KeeperName, c.CategoryID +ORDER BY c.FullName, k.KeeperName"; + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + dictionary2.Add( + new Tuple(sqLiteDataReader.GetInt32(0), sqLiteDataReader.GetString(3), + sqLiteDataReader.GetInt32(1)), + new Tuple(sqLiteDataReader.GetString(2), + sqLiteDataReader.GetDecimal(4), sqLiteDataReader.GetDecimal(5))); + } + + command.CommandText = @" +SELECT t.ParentID, c.CategoryID, c.FullName,SUM(Count)Count, SUM(Size)Size +FROM + ( + SELECT CategoryID, ParentID FROM Category WHERE ParentID > 1000000 UNION + SELECT c1.CategoryID, c2.ParentID FROM Category AS c1 JOIN Category AS c2 ON (c1.ParentID = c2.CategoryID) WHERE c2.ParentID > 1000000 + ) AS t + JOIN Category AS c ON (t.CategoryID = c.CategoryID) + JOIN Keeper AS k ON (k.CategoryID = t.CategoryID AND k.KeeperName <> 'All') +GROUP BY + c.CategoryID, c.FullName +ORDER BY c.FullName"; + + using (var sqLiteDataReader = command.ExecuteReader()) + { + while (sqLiteDataReader.Read()) + tupleList.Add(new Tuple(sqLiteDataReader.GetInt32(0), + sqLiteDataReader.GetInt32(1), sqLiteDataReader.GetString(2), + sqLiteDataReader.GetDecimal(3), sqLiteDataReader.GetDecimal(4))); + } + + var rootCategoryReportTemplate = Settings.Current.ReportCategoriesTemplate; + foreach (var num1 in source1.Select(x => x.Key)) + { + var c = num1; + var rootCategoryReportData = new Dictionary + { + {"today", DateTime.Now.ToString("dd.MM.yyyy")}, + {"topics_count", source1[c].Item2}, + {"topics_size", source1[c].Item3.ToString("N")}, + {"keepers", new List()}, + {"categories", new List()} + }; + var num2 = 1; + var source2 = dictionary1; + foreach (var keyValuePair1 in + source2.Where(x => x.Key.Item1 == c)) + { + var categoriesList = new List(); + var k = keyValuePair1; + ((List) rootCategoryReportData["keepers"]).Add(new Dictionary + { + {"keeper_number", num2}, + {"keeper_username", k.Key.Item2}, + {"keep_topics_count", k.Value.Item2}, + {"keep_topics_size", k.Value.Item3.ToString("N")}, + {"categories", categoriesList} + }); + + var source3 = dictionary2; + foreach (var + keyValuePair2 in source3.Where(x => x.Key.Item2 == k.Key.Item2 && x.Key.Item1 == c)) + categoriesList.Add(new Dictionary + { + {"keep_category_name", keyValuePair2.Value.Item1}, + {"keep_category_topics_count", keyValuePair2.Value.Item2}, + {"keep_category_topics_size", keyValuePair2.Value.Item3.ToString("N")} + }); + + ++num2; + } + + var source4 = tupleList; + foreach (var tuple in source4.Where(x => x.Item1 == c) + .OrderBy(x => x.Item3)) + { + var k = tuple; + var keepersList = new List(); + ((List) rootCategoryReportData["categories"]).Add(new Dictionary + { + {"category_name", k.Item3}, + {"topics_count", k.Item4}, + {"topics_size", k.Item5.ToString("N")}, + {"keepers", keepersList} + }); + var source3 = dictionary2; + foreach (var keyValuePair + in source3.Where(x => x.Key.Item3 == k.Item2).OrderBy(x => x.Key.Item2)) + keepersList.Add(new Dictionary + { + {"keeper_username", keyValuePair.Key.Item2}, + {"keep_topics_count", keyValuePair.Value.Item2}, + {"keep_topics_size", keyValuePair.Value.Item3.ToString("N")} + }); + } + + reports.Add(c, new Dictionary()); + reports[c].Add(0, Stubble.Render(rootCategoryReportTemplate, rootCategoryReportData)); + } + + ClientLocalDb.Current.SaveReports(reports); + } + } + } +} \ No newline at end of file diff --git a/TLO/SenderMethods.cs b/TLO/SenderMethods.cs new file mode 100644 index 0000000..cfe5c2d --- /dev/null +++ b/TLO/SenderMethods.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Windows.Forms; +using TLO.Clients; +using TLO.Info; + +namespace TLO +{ + internal static class SenderMethods + { + public static void SendTorrentFileToTorrentClient(List topics, Category category) + { + var torrentClientInfo = ClientLocalDb.Current.GetTorrentClients() + .Where(x => x.UID == category.TorrentClientUID).FirstOrDefault(); + if (torrentClientInfo == null) + return; + var torrentClient1 = torrentClientInfo.Create(); + if (torrentClient1 == null) + return; + if (string.IsNullOrWhiteSpace(category.Folder)) + throw new Exception("В разделе не указан каталог для загрузки"); + foreach (var topic in topics) + if (topic.Status != 7 && topic.Status != 4) + { + int topicId; + if (category.CreateSubFolder != 0) + { + if (category.CreateSubFolder != 1) + throw new Exception("Не поддерживается указаный метод создания подкаталога"); + var torrentClient2 = torrentClient1; + var folder = category.Folder; + topicId = topic.TopicID; + var path2 = topicId.ToString(); + var dir = Path.Combine(folder, path2); + torrentClient2.SetDefaultFolder(dir); + } + + var buffer1 = new byte[0]; + if (buffer1.Length == 0) + buffer1 = RuTrackerOrg.Current.DownloadTorrentFile(topic.TopicID); + if (buffer1 == null) + break; + var torrentClient3 = torrentClient1; + string path; + if (category.CreateSubFolder != 1) + { + path = category.Folder; + } + else + { + var folder = category.Folder; + topicId = topic.TopicID; + var path2 = topicId.ToString(); + path = Path.Combine(folder, path2); + } + + var filename = string.Format("[rutracker.org].t{0}.torrent", topic.TopicID); + var fdata = buffer1; + torrentClient3.SendTorrentFile(path, filename, fdata); + if (category.IsSaveTorrentFiles) + { + if (!Directory.Exists(category.FolderTorrentFile)) + Directory.CreateDirectory(category.FolderTorrentFile); + using (var fileStream = File.Create(Path.Combine(category.FolderTorrentFile, + string.Format("[rutracker.org].t{0}.torrent", topic.TopicID)))) + { + fileStream.Write(buffer1, 0, buffer1.Count()); + } + } + + if (category.IsSaveWebPage) + { + Thread.Sleep(500); + var buffer2 = RuTrackerOrg.Current.DownloadWebPages(string.Format( + "https://{1}/forum/viewtopic.php?t={0}", topic.TopicID, Settings.Current.HostRuTrackerOrg)); + if (!Directory.Exists(category.FolderSavePageForum)) + Directory.CreateDirectory(category.FolderSavePageForum); + using (var fileStream = File.Create(Path.Combine(category.FolderSavePageForum, + string.Format("[rutracker.org].t{0}.html", topic.TopicID)))) + { + fileStream.Write(buffer2, 0, buffer2.Count()); + } + } + + Thread.Sleep(500); + } + } + + public static void SendTorrentFileToTorrentClient(TopicInfo topic, Category category) + { + if (topic == null || category == null) + return; + SendTorrentFileToTorrentClient(new List + { + topic + }, category); + } + + public static void SendReportToForum() + { + foreach (var report in ClientLocalDb.Current.GetReports( + new int?())) + if (!string.IsNullOrWhiteSpace(report.Value.Item1)) + RuTrackerOrg.Current.SendReport(report.Value.Item1, report.Value.Item2); + } + + public static void SendReportToForum(ProgressBar pBar) + { + var reports = ClientLocalDb.Current.GetReports(new int?()); + pBar.Visible = true; + pBar.Minimum = 1; + pBar.Maximum = reports.Count; + pBar.Value = 1; + pBar.Step = 1; + foreach (var keyValuePair in reports) + { + if (!string.IsNullOrWhiteSpace(keyValuePair.Value.Item1)) + RuTrackerOrg.Current.SendReport(keyValuePair.Value.Item1, keyValuePair.Value.Item2); + pBar.PerformStep(); + } + } + } +} \ No newline at end of file diff --git a/TLO/Settings.cs b/TLO/Settings.cs new file mode 100644 index 0000000..cf2168c --- /dev/null +++ b/TLO/Settings.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Text; +using System.Windows.Forms; +using System.Xml.Serialization; +using NLog; +using NLog.Config; +using NLog.Targets; + +namespace TLO +{ + public class Settings + { + private static readonly Logger Logger = LogManager.GetLogger("Settings"); + private static Settings _data; + private DateTime _lastWriteTime; + + public Settings() + { + KeeperName = string.Empty; + KeeperPass = string.Empty; + CountDaysKeepHistory = 7; + PeriodRunAndStopTorrents = 60; + CountSeedersReport = 10; + IsSelectLessOrEqual = true; + IsNotSaveStatistics = true; + ReportLine = "[*] %%Status%% [url=viewtopic.php?t=%%ID%%]%%Name%%[/url] %%Size%%"; + ReportTop1 = + "[b]Актуально на:[/b] %%CreateDate%%\r\n\r\nОбщее количество хранимых раздач подраздела: %%CountTopics%% шт. (%%SizeTopics%%)"; + ReportTop2 = + "%%Top1%%[spoiler=\"Раздачи, взятые на хранение, №№ %%NumberTopicsFirst%% - %%NumberTopicsLast%%\"]\r\n[list=1]\r\n%%ReportLines%%\r\n[/list]\r\n[/spoiler]"; + ReportBottom = ""; + ReportSummaryTemplate = @" +Актуально на: {{{today}}} + +Общее количество хранимых раздач: {{{summary_topics_count}}} шт. +Общий вес хранимых раздач: {{{summary_topics_size}}} GB +[hr] + +{{#categories}} +[url={{{url}}}]{{{category_name}}}[/url] - {{{topics_count}}} шт. ({{{topics_size}}} GB) +{{/categories}} +".Trim(); + ReportCategoryHeaderTemplate = @" +[url={{{category_uri}}}][color=darkgreen][b]{{{category_name}}}[/b][/color][/url] | [url={{{category_check_seeds_uri}}}][color=darkgreen][b]Проверка сидов[/b][/color][/url] + +[b]Актуально на:[/b] {{{today}}} + +[b]Общее количество раздач в подразделе:[/b] {{{topics_count}}} шт. +[b]Общий размер раздач в подразделе:[/b] {{{topics_size}}} GB. +[b]Количество хранителей:[/b] {{{keepers_count}}} +[b]Общее количество хранимых раздач:[/b] {{{keep_topics_count}}} шт. +[b]Общий вес хранимых раздач:[/b] {{{keep_topics_size}}} GB. +[hr] + +{{#keepers}} +[b]Хранитель {{{keeper_number}}}:[/b] [url={{{keeper_profile_uri}}}][color=darkgreen][b]{{{keeper_username}}}[/b][/color][/url] - {{{keep_topics_count}}} шт. ({{{keep_topics_size}}} GB) +{{/keepers}} +".Trim(); + ReportCategoriesTemplate = @" +[hr] +[hr] +[b][color=darkgreen][align=center][size=16]Статистика раздела: {{{today}}}[/size][/align][/color][/b][hr] +[hr] + +Всего: {{{topics_count}}} шт. ({{{topics_size}}} Гб.) + +[hr] +[size=12][b]По хранителям:[/b][/size] +{{#keepers}} +[spoiler=""{{{keeper_number}}}. {{{keeper_username}}} - {{{keep_topics_count}}} шт. ({{{keep_topics_size}}} Гб.)""] +{{#categories}} +{{{keep_category_name}}} - {{{keep_category_topics_count}}} шт. ({{{keep_category_topics_size}}} Гб.) +{{/categories}} +[/spoiler] +{{/keepers}} +[hr] +[size=12][b]По форумам:[/b][/size] +{{#categories}} +[spoiler=""{{{category_name}}} - {{{topics_count}}} шт. ({{{topics_size}}} Гб.)""] +{{#keepers}} +{{{keeper_username}}} - {{{keep_topics_count}}} шт. ({{{keep_topics_size}}} Гб.) +{{/keepers}} +[/spoiler] +{{/categories}} +".Trim(); + HostRuTrackerOrg = "rutracker.org"; + ProxyList = new List(); + WindowSize = Size.Empty; + WindowLocation = Point.Empty; + SettingsWindowSize = Size.Empty; + SettingsWindowLocation = Point.Empty; + ShowInTray = false; + HideToTray = false; + CloseToTray = false; + NotificationInTray = false; + DontRunCopy = true; + } + + private static string FileSettings => Path.Combine(Folder, "TLO.Settings.xml"); + private static string OldFileSettings => Path.Combine(Folder, "TLO.local.Settings.xml"); + + public static string Folder => Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); + + public static Settings Current + { + get + { + if (_data == null) + _data = new Settings(); + _data.Checking(); + return _data; + } + } + + [XmlElement] public int? LogLevel; + [XmlAttribute] public string KeeperName; + [XmlAttribute] public string KeeperPass; + [XmlAttribute] public bool IsUpdateStatistics; + [XmlAttribute] public int CountDaysKeepHistory; + [XmlAttribute] public int PeriodRunAndStopTorrents; + [XmlAttribute] public int CountSeedersReport; + [XmlAttribute] public bool IsAvgCountSeeders; + [XmlAttribute] public bool IsSelectLessOrEqual; + [XmlAttribute] public bool IsNotSaveStatistics; + [XmlAttribute] public DateTime LastUpdateTopics; + [XmlElement] public string ReportTop1; + [XmlElement] public string ReportTop2; + [XmlElement] public string ReportLine; + [XmlElement] public string ReportBottom; + [XmlElement] public string ReportSummaryTemplate; + [XmlElement] public string ReportCategoryHeaderTemplate; + [XmlElement] public string ReportCategoriesTemplate; + [XmlElement] public string HostRuTrackerOrg; + [XmlElement] public bool? LoadDBInMemory; + [XmlElement] public bool? UseProxy; + [XmlElement] public bool? SystemProxy; + [XmlElement] public string SelectedProxy; + [XmlArray] public List ProxyList; + [XmlElement] public bool? DisableServerCertVerify; + [XmlElement] public string ApiHost; + [XmlElement] public Size WindowSize; + [XmlElement] public Point WindowLocation; + [XmlElement] public Size SettingsWindowSize; + [XmlElement] public Point SettingsWindowLocation; + [XmlElement] public bool ShowInTray; + [XmlElement] public bool HideToTray; + [XmlElement] public bool CloseToTray; + [XmlElement] public bool NotificationInTray; + [XmlElement] public bool DontRunCopy; + + public void Save() + { + lock (this) + { + try + { + if (!Directory.Exists(Path.GetDirectoryName(FileSettings))) + Directory.CreateDirectory(Path.GetDirectoryName(FileSettings)); + using (Stream stream = File.Open(FileSettings, FileMode.Create, FileAccess.ReadWrite)) + { + LogLevel = LogLevel.HasValue ? LogLevel.Value : 0; + new XmlSerializer(typeof(Settings)).Serialize(stream, this); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); + } + + _lastWriteTime = File.GetLastWriteTime(FileSettings); + } + } + + private void Read() + { + lock (this) + { + // Проверка наличия старого файла с настройками + if (File.Exists(OldFileSettings) && !File.Exists(FileSettings)) + { + File.Move(OldFileSettings, FileSettings); + } + + if (!File.Exists(FileSettings)) Save(); + + using (Stream stream = File.Open(FileSettings, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + var settings = (Settings) new XmlSerializer(typeof(Settings)).Deserialize(stream); + IsUpdateStatistics = settings.IsUpdateStatistics; + CountDaysKeepHistory = settings.CountDaysKeepHistory; + PeriodRunAndStopTorrents = settings.PeriodRunAndStopTorrents; + CountSeedersReport = settings.CountSeedersReport; + IsAvgCountSeeders = settings.IsAvgCountSeeders; + KeeperName = settings.KeeperName; + KeeperPass = settings.KeeperPass; + IsSelectLessOrEqual = settings.IsSelectLessOrEqual; + IsNotSaveStatistics = settings.IsNotSaveStatistics; + LastUpdateTopics = settings.LastUpdateTopics; + ReportTop1 = settings.ReportTop1.Replace("\n", "\r\n").Replace("\r\r", "\r"); + ReportTop2 = settings.ReportTop2.Replace("\n", "\r\n").Replace("\r\r", "\r"); + ReportLine = settings.ReportLine.Replace("\n", "\r\n").Replace("\r\r", "\r"); + ReportBottom = settings.ReportBottom.Replace("\n", "\r\n").Replace("\r\r", "\r"); + ReportSummaryTemplate = + settings.ReportSummaryTemplate.Replace("\n", "\r\n").Replace("\r\r", "\r"); + ReportCategoryHeaderTemplate = settings.ReportCategoryHeaderTemplate.Replace("\n", "\r\n") + .Replace("\r\r", "\r"); + ReportCategoriesTemplate = settings.ReportCategoriesTemplate.Replace("\n", "\r\n") + .Replace("\r\r", "\r"); + HostRuTrackerOrg = settings.HostRuTrackerOrg; + SetLogger(settings.LogLevel.HasValue ? settings.LogLevel.Value : 0); + _lastWriteTime = File.GetLastWriteTime(FileSettings); + LoadDBInMemory = settings.LoadDBInMemory; + UseProxy = settings.UseProxy; + SystemProxy = settings.SystemProxy; + SelectedProxy = settings.SelectedProxy; + ProxyList = settings.ProxyList; + ApiHost = settings.ApiHost; + DisableServerCertVerify = settings.DisableServerCertVerify; + WindowSize = settings.WindowSize; + WindowLocation = settings.WindowLocation; + SettingsWindowSize = settings.WindowSize; + SettingsWindowLocation = settings.SettingsWindowLocation; + ShowInTray = settings.ShowInTray; + HideToTray = settings.HideToTray; + CloseToTray = settings.CloseToTray; + NotificationInTray = settings.NotificationInTray; + DontRunCopy = settings.DontRunCopy; + } + } + } + + private void Checking() + { + if (!(File.GetLastWriteTime(FileSettings) != _lastWriteTime)) + return; + Read(); + } + + private void SetLogger(int logLevel) + { + if (LogLevel.HasValue && LogLevel.Value == logLevel) + return; + var str = "BI.Analytics.Expert.Other"; + if (Assembly.GetEntryAssembly() != null) + str = Assembly.GetEntryAssembly().ManifestModule.Name; + var loggingConfiguration = new LoggingConfiguration(); + var fileTarget = new FileTarget(); + fileTarget.Layout = "${date:format=yyyy-MM-dd HH\\:mm\\:ss}\t${level}\t${logger}\t${message}"; + loggingConfiguration.AddTarget("logfile", fileTarget); + fileTarget.FileName = Path.Combine(Folder, str + ".log"); + fileTarget.Encoding = Encoding.UTF8; + fileTarget.ArchiveAboveSize = 20971520L; + if (Environment.UserInteractive) + { + var coloredConsoleTarget = new ColoredConsoleTarget(); + loggingConfiguration.AddTarget("console", coloredConsoleTarget); + coloredConsoleTarget.Layout = + "${date:format=yyyy-MM-dd HH\\:mm\\:ss}\t${level}\t${logger}\t${message}\t${file}:${line}"; + var loggingRule = new LoggingRule("*", NLog.LogLevel.Debug, coloredConsoleTarget); + loggingConfiguration.LoggingRules.Add(loggingRule); + } + + var loggingRule1 = logLevel > 0 + ? logLevel != 1 + ? logLevel != 2 + ? new LoggingRule("*", NLog.LogLevel.Trace, fileTarget) + : new LoggingRule("*", NLog.LogLevel.Debug, fileTarget) + : new LoggingRule("*", NLog.LogLevel.Info, fileTarget) + : new LoggingRule("*", NLog.LogLevel.Warn, fileTarget); + loggingConfiguration.LoggingRules.Add(loggingRule1); + LogManager.Configuration = loggingConfiguration; + Logger.Info(string.Format("OS: {0} (Is64BitOperatingSystem: {1}, Version {2})", + Environment.OSVersion.VersionString, Environment.Is64BitOperatingSystem, + Environment.OSVersion.Version)); + LogLevel = logLevel; + } + } +} \ No newline at end of file diff --git a/TLO/TLO.csproj b/TLO/TLO.csproj new file mode 100644 index 0000000..e69038d --- /dev/null +++ b/TLO/TLO.csproj @@ -0,0 +1,292 @@ + + + + + + Debug + AnyCPU + {636EBECD-92E1-45FD-87A1-129E110C72AA} + WinExe + TLO + TLO + v4.7.2 + 512 + true + true + 8 + enable + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + false + false + 42 + 2.17.0.%2a + true + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + none + true + bin\Release\ + TRACE + prompt + 4 + false + + + hdd.ico + + + 70B8EDED1127918B508D94213D7C0757DF2DAEC2 + + + + + + true + + + true + + + + ..\packages\AngleSharp.1.0.0-alpha-819\lib\net472\AngleSharp.dll + True + + + ..\packages\HttpToSocks5Proxy.1.4.0\lib\net45\MihaZupan.HttpToSocks5Proxy.dll + + + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + True + + + ..\packages\NLog.4.6.8\lib\net45\NLog.dll + + + ..\packages\Stubble.Compilation.1.6.3\lib\net45\Stubble.Compilation.dll + True + + + ..\packages\Stubble.Core.1.6.3\lib\net45\Stubble.Core.dll + True + + + + ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + True + + + ..\packages\System.Collections.Immutable.1.7.0\lib\netstandard2.0\System.Collections.Immutable.dll + True + + + + + + ..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll + True + + + ..\packages\System.Data.SQLite.EF6.1.0.112.0\lib\net46\System.Data.SQLite.EF6.dll + True + + + ..\packages\System.Data.SQLite.Linq.1.0.112.0\lib\net46\System.Data.SQLite.Linq.dll + True + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + True + + + + ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + True + + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0-preview.4.20251.6\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + True + + + + ..\packages\System.Text.Encoding.CodePages.5.0.0-preview.4.20251.6\lib\net461\System.Text.Encoding.CodePages.dll + True + + + ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + True + + + + + + + + + + + + + + + + + + + + + Component + + + + + Form + + + FolderNameDialog.cs + + + UserControl + + + ForumPages.cs + + + Form + + + GetLabelName.cs + + + Form + + + MainForm.cs + + + Form + + + SelectCategory.cs + + + Form + + + SettingsForm.cs + + + + + + + + + + + + + + + + + + FolderNameDialog.cs + + + ForumPages.cs + + + GetLabelName.cs + + + MainForm.cs + + + SelectCategory.cs + + + SettingsForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 и x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + + + + + + \ No newline at end of file diff --git a/TLO/Tools/ProxySource.cs b/TLO/Tools/ProxySource.cs new file mode 100644 index 0000000..1020cd6 --- /dev/null +++ b/TLO/Tools/ProxySource.cs @@ -0,0 +1,10 @@ +namespace TLO.Tools +{ + internal static class ProxySource + { + public static string[] GetList() + { + return new string[0]; + } + } +} \ No newline at end of file diff --git a/TLO/Tools/SettingsProvider.cs b/TLO/Tools/SettingsProvider.cs new file mode 100644 index 0000000..b8ccccb --- /dev/null +++ b/TLO/Tools/SettingsProvider.cs @@ -0,0 +1,84 @@ +using System.Collections.Specialized; +using System.Configuration; +using System.Linq; + +namespace TLO.Tools +{ + public class SettingsProvider : System.Configuration.SettingsProvider, IApplicationSettingsProvider + { + private static readonly string[] KnownProperties = + { + "WindowSize", + "WindowLocation", + "SettingsWindowSize", + "SettingsWindowLocation", + "ShowInTray", + "HideToTray", + "CloseToTray", + "NotificationInTray", + "DontRunCopy", + }; + + public override void Initialize(string name, NameValueCollection config) + { + if (string.IsNullOrEmpty(name)) name = nameof(GetType); + base.Initialize(name, config); + } + + public override SettingsPropertyValueCollection GetPropertyValues( + SettingsContext context, + SettingsPropertyCollection collection + ) + { + var result = new SettingsPropertyValueCollection(); + foreach (SettingsProperty property in collection) + { + var value = new SettingsPropertyValue(property); + if (KnownProperties.Contains(property.Name)) + { + value.PropertyValue = Settings + .Current + .GetType() + .GetField(value.Property.Name) + .GetValue(Settings.Current); + } + + result.Add(value); + } + + return result; + } + + public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) + { + foreach (SettingsPropertyValue value in collection) + { + if (KnownProperties.Contains(value.Property.Name)) + { + Settings + .Current + .GetType() + .GetField(value.Property.Name) + .SetValue(Settings.Current, value.PropertyValue); + } + } + + Settings.Current.Save(); + } + + public override string ApplicationName { get; set; } + + public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property) + { + return null; + } + + public void Reset(SettingsContext context) + { + } + + public void Upgrade(SettingsContext context, SettingsPropertyCollection properties) + { + } + } +} \ No newline at end of file diff --git a/TLO/Tools/UpdaterMethods.cs b/TLO/Tools/UpdaterMethods.cs new file mode 100644 index 0000000..f54ac89 --- /dev/null +++ b/TLO/Tools/UpdaterMethods.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using TLO.Clients; +using TLO.Info; + +namespace TLO.Tools +{ + internal static class UpdaterMethods + { + public static void UpdateSeedersByCategories(List categories = null) + { + if (categories == null) + categories = ClientLocalDb.Current.GetCategoriesEnable(); + if (categories == null) + return; + foreach (var category in categories) + ClientLocalDb.Current.SaveStatus(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID), true); + } + + public static void UpdateSeedersByCategory(Category category) + { + if (category == null) + return; + UpdateSeedersByCategories(new List + { + category + }); + } + + public static void UpdateTopicsByCategories(List categories = null) + { + if (categories == null) + categories = ClientLocalDb.Current.GetCategoriesEnable(); + if (categories == null) + return; + foreach (var category in categories) + ClientLocalDb.Current.SaveTopicInfo( + RuTrackerOrg.Current.GetTopicsInfo(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID) + .Select(x => x[0]).Distinct().ToArray()), true); + } + + public static void UpdateTopicsByCategories(ProgressBar pBar) + { + var categoriesEnable = ClientLocalDb.Current.GetCategoriesEnable(); + pBar.Visible = true; + pBar.Minimum = 1; + pBar.Maximum = categoriesEnable.Count; + pBar.Value = 1; + pBar.Step = 1; + foreach (var category in categoriesEnable) + { + ClientLocalDb.Current.SaveTopicInfo( + RuTrackerOrg.Current.GetTopicsInfo(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID) + .Select(x => x[0]).Distinct().ToArray()), true); + pBar.PerformStep(); + } + } + + public static void UpdateTopicsByCategory(Category category) + { + if (category == null) + return; + UpdateTopicsByCategories(new List + { + category + }); + } + + public static void UpdateHashFromClients(List clients = null) + { + if (clients == null) + clients = ClientLocalDb.Current.GetTorrentClients(); + if (clients == null) + return; + foreach (var client in clients) + { + var torrentClient = client.Create(); + if (torrentClient != null) + ClientLocalDb.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); + } + } + + public static void UpdateHashFromClients(TorrentClientInfo client) + { + if (client == null) + return; + UpdateHashFromClients(new List + { + client + }); + } + + internal static void UpdateHashFromClients(ProgressBar pBar) + { + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + pBar.Visible = true; + pBar.Minimum = 1; + pBar.Maximum = torrentClients.Count; + pBar.Value = 1; + pBar.Step = 1; + foreach (var torrentClientInfo in torrentClients) + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + ClientLocalDb.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); + + pBar.PerformStep(); + } + } + + public static void UpdateHashFromClients(Guid uid) + { + var client = ClientLocalDb.Current.GetTorrentClients() + .Where(x => x.UID == uid).FirstOrDefault(); + if (client == null) + return; + UpdateHashFromClients(client); + Reports.CreateReportByRootCategories(); + } + } +} \ No newline at end of file diff --git a/TLO/TrayObject.cs b/TLO/TrayObject.cs new file mode 100644 index 0000000..044aa6e --- /dev/null +++ b/TLO/TrayObject.cs @@ -0,0 +1,39 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using TLO.Forms; + +namespace TLO +{ + public static class TrayObject + { + private static NotifyIcon _trayIcon; + + public static NotifyIcon TrayIcon + { + get + { + NotifyIcon CreateIconTrayIcon() + { + var icon = new NotifyIcon + { + Icon = (Icon) new ComponentResourceManager(typeof(MainForm)).GetObject("$this.Icon"), + ContextMenu = new ContextMenu(new MenuItem[] { }), + Visible = false + }; + + icon.MouseClick += (sender, args) => OnClick?.Invoke(icon, args); + + return icon; + } + + return _trayIcon ??= CreateIconTrayIcon(); + } + } + + public delegate void TrayEventHandler(object sender, MouseEventArgs args); + + public static event TrayEventHandler OnClick; + } +} diff --git a/TLO/WindowTrayAssociation.cs b/TLO/WindowTrayAssociation.cs new file mode 100644 index 0000000..7ba4964 --- /dev/null +++ b/TLO/WindowTrayAssociation.cs @@ -0,0 +1,88 @@ +using System.Windows.Forms; + +namespace TLO +{ + public class WindowTrayAssociation + { + private readonly Form _form; + private bool _iconAlwaysShown; + + public WindowTrayAssociation(Form form) + { + _form = form; + + Properties.Settings.Default.PropertyChanged += (sender, args) => + { + if (args.PropertyName == "ShowInTray") + { + SyncSettings(); + } + }; + + TrayObject.OnClick += (sender, args) => + { + if ((args.Button & MouseButtons.Left) == 0) + { + return; + } + + if (!_form.Visible) + { + _form.ShowInTaskbar = true; + _form.Visible = true; + } + else if (_form.WindowState == FormWindowState.Normal) + { + if (Properties.Settings.Default.HideToTray) + { + _form.WindowState = FormWindowState.Minimized; + _form.ShowInTaskbar = false; + TrayObject.TrayIcon.Visible = true; + } + } + else if (_form.WindowState == FormWindowState.Minimized) + { + _form.WindowState = FormWindowState.Normal; + _form.ShowInTaskbar = true; + } + + SyncSettings(); + }; + + _form.Resize += (sender, args) => + { + if (_form.WindowState == FormWindowState.Minimized && Properties.Settings.Default.HideToTray) + { + _form.ShowInTaskbar = false; + TrayObject.TrayIcon.Visible = true; + } + }; + + _form.FormClosing += (sender, args) => + { + if (Properties.Settings.Default.CloseToTray && args.CloseReason == CloseReason.UserClosing) + { + _form.Hide(); + _form.ShowInTaskbar = false; + TrayObject.TrayIcon.Visible = true; + args.Cancel = true; + } + else + { + TrayObject.TrayIcon.Visible = false; + } + }; + } + + public void SyncSettings() + { + _iconAlwaysShown = Properties.Settings.Default.ShowInTray; + TrayObject.TrayIcon.Visible = _iconAlwaysShown || + _form.WindowState == FormWindowState.Minimized && + ( + Properties.Settings.Default.HideToTray || + Properties.Settings.Default.CloseToTray + ); + } + } +} \ No newline at end of file diff --git a/TLO/WorkerMethods.cs b/TLO/WorkerMethods.cs new file mode 100644 index 0000000..d24833e --- /dev/null +++ b/TLO/WorkerMethods.cs @@ -0,0 +1,1034 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using NLog; +using TLO.Clients; +using TLO.Forms; +using TLO.Info; + +namespace TLO +{ + internal static class WorkerMethods + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + public static Logger logger = LogManager.GetCurrentClassLogger(); + + public static void bwDownloadTorrentFiles(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + var tuple = e.Argument as Tuple, MainForm>; + var topicInfoList = tuple.Item1; + var folder = string.Empty; + if (topicInfoList == null || topicInfoList.Count == 0) + return; + tuple.Item2.Invoke((MethodInvoker) delegate + { + var folderBrowserDialog = new FolderBrowserDialog(); + if (folderBrowserDialog.ShowDialog() != DialogResult.OK) + return; + folder = folderBrowserDialog.SelectedPath; + }); + if (string.IsNullOrWhiteSpace(folder)) + { + int num2; + tuple.Item2.Invoke((MethodInvoker) delegate + { + num2 = (int) MessageBox.Show("Не указан каталог для сохранения торрент-файлов", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + }); + } + else + { + foreach (var topicInfo in topicInfoList) + { + var buffer = RuTrackerOrg.Current.DownloadTorrentFile(topicInfo.TopicID); + if (buffer != null) + { + using (var fileStream = File.Create(Path.Combine(folder, + string.Format("[rutracker.org].t{0}.torrent", topicInfo.TopicID)))) + { + fileStream.Write(buffer, 0, buffer.Count()); + } + + num1 += new decimal(1000, 0, 0, false, 1) / topicInfoList.Count; + backgroundWorker.ReportProgress((int) num1); + } + } + } + } + catch (Exception ex) + { + Logger.Error(ex.Message); + Logger.Debug(ex); + var num2 = (int) MessageBox.Show("Произошла ошибка при скачивании торрент-файлов:\r\n" + ex.Message, + "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwSendTorrentFileToTorrentClient(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + var tuple = + e.Argument as Tuple, Category>; + var topicInfoList = tuple.Item2; + var category = tuple.Item3; + Logger.Info("Запущена задача на скачивание и добавление торрент-файлов в торрент-клиент..."); + Logger.Trace(string.Format("\tКол-во раздач для скачивания торрент-файлов: {0}", + topicInfoList.Count)); + var torrentClientInfo = ClientLocalDb.Current.GetTorrentClients() + .Where(x => x.UID == category.TorrentClientUID) + .FirstOrDefault(); + var source = torrentClientInfo.Create().GetAllTorrentHash() + .Where(x => !string.IsNullOrWhiteSpace(x.Hash)); + foreach (var topicInfo1 in topicInfoList) + { + var t = topicInfo1; + var topicInfo2 = source.Where(x => x.Hash == t.Hash) + .FirstOrDefault(); + if (topicInfo2 != null) + t.TorrentName = topicInfo2.TorrentName; + } + + var list = source.Select(x => x.Hash) + .ToList(); + if (torrentClientInfo == null) + { + Logger.Warn("Не указан торрент-клиент в категории/подфоруме"); + } + else + { + var folder = category.Folder; + if (string.IsNullOrWhiteSpace(folder)) + tuple.Item1.Invoke((MethodInvoker) delegate + { + var folderBrowserDialog = new FolderBrowserDialog(); + if (folderBrowserDialog.ShowDialog() != DialogResult.OK) + return; + folder = folderBrowserDialog.SelectedPath; + }); + if (string.IsNullOrWhiteSpace(folder)) + throw new Exception("Не указан каталог для загрузки"); + foreach (var topicInfo in topicInfoList) + { + var t = topicInfo; + try + { + if (t.Status != 7) + { + if (t.Status != 4) + { + var folder2 = string.Empty; + if (category.CreateSubFolder == 0) + { + folder2 = folder; + } + else if (category.CreateSubFolder == 1) + { + folder2 = Path.Combine(folder, t.TopicID.ToString()); + } + else + { + if (category.CreateSubFolder != 2) + throw new Exception( + "Не поддерживается указаный метод создания подкаталога"); + var result = DialogResult.None; + tuple.Item1.Invoke((MethodInvoker) delegate + { + var folderNameDialog = new FolderNameDialog(); + folderNameDialog.SelectedPath = t.Name; + result = folderNameDialog.ShowDialog(); + folder2 = Path.Combine(folder, folderNameDialog.SelectedPath); + }); + if (result == DialogResult.Abort) + return; + if (result != DialogResult.Cancel) + { + if (result != DialogResult.OK) + throw new Exception("result != DialogResult.OK"); + } + else + { + continue; + } + } + + if (!list.Contains(t.Hash)) + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient == null) + throw new ArgumentException( + "Не удалось создать подключение к торрент-клиенту \"" + + torrentClientInfo.Name + "\""); + torrentClient.SetDefaultFolder(folder2); + var numArray = RuTrackerOrg.Current.DownloadTorrentFile(t.TopicID); + if (numArray == null) + { + Logger.Warn("Не удалось скачать торрент-файл для раздачи \"" + + t.Name + "\". Статус раздачи: " + t.Status); + continue; + } + + torrentClient.SendTorrentFile(folder2, + string.Format("[rutracker.org].t{0}.torrent", t.TopicID), + numArray); + torrentClient.SetLabel(t.Hash, + string.IsNullOrWhiteSpace(category.Label) + ? category.FullName + : category.Label); + if (category.IsSaveTorrentFiles) + { + if (!Directory.Exists(category.FolderTorrentFile)) + Directory.CreateDirectory(category.FolderTorrentFile); + using (var fileStream = File.Create( + Path.Combine(category.FolderTorrentFile, + string.Format("[rutracker.org].t{0}.torrent", t.TopicID)))) + { + fileStream.Write(numArray, 0, + numArray.Count()); + } + } + } + + if (category.IsSaveWebPage) + { + Thread.Sleep(500); + var buffer = RuTrackerOrg.Current.DownloadWebPages( + string.Format("https://{1}/forum/viewtopic.php?t={0}", t.TopicID, + Settings.Current.HostRuTrackerOrg)); + if (!Directory.Exists(category.FolderSavePageForum)) + Directory.CreateDirectory(category.FolderSavePageForum); + using (var fileStream = File.Create( + Path.Combine(category.FolderSavePageForum, + string.Format("[rutracker.org].t{0}.html", t.TopicID)))) + { + fileStream.Write(buffer, 0, buffer.Count()); + } + } + + if (!string.IsNullOrWhiteSpace(t.TorrentName)) + { + if (Directory.Exists(Path.Combine(category.Folder, t.TorrentName))) + { + if (!Directory.Exists(Path.Combine(category.Folder, + t.TopicID.ToString()))) + Directory.CreateDirectory(Path.Combine(category.Folder, + t.TopicID.ToString())); + Directory.Move(Path.Combine(category.Folder, t.TorrentName), + Path.Combine(category.Folder, t.TopicID.ToString(), t.TorrentName)); + continue; + } + + if (File.Exists(Path.Combine(category.Folder, t.TorrentName))) + { + if (!Directory.Exists(Path.Combine(category.Folder, + t.TopicID.ToString()))) + Directory.CreateDirectory(Path.Combine(category.Folder, + t.TopicID.ToString())); + File.Move(Path.Combine(category.Folder, t.TorrentName), + Path.Combine(category.Folder, t.TopicID.ToString(), t.TorrentName)); + continue; + } + } + } + else + { + continue; + } + } + else + { + continue; + } + } + catch (Exception ex) + { + Logger.Warn( + "Не удалось скачать или добавить в торрент-клиент торрент-файл для раздачи \"" + + t.Name + "\". Статус раздачи: " + t.Status + "\t\t" + ex.Message); + } + + num1 += new decimal(1000, 0, 0, false, 1) / topicInfoList.Count; + backgroundWorker.ReportProgress((int) num1); + } + + Logger.Info("Завершена задача на скачивание и добавление торрент-файлов в торрент-клиент."); + } + } + catch (Exception ex) + { + Logger.Error("Произошла ошибка при скачивании и добавлении торрент-файлов в торрент-клиент: " + + ex.Message); + Logger.Debug(ex); + var num2 = (int) MessageBox.Show("Поизошла ошибка при скачивании торрент-файлов:\r\n" + ex.Message, + "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwSetLabels(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + var tuple = e.Argument as Tuple, string>; + var topicInfoList = tuple.Item2; + var label = tuple.Item3; +// logger.Info("Запущена задача на установку пользовательских меток в торрент-клиент..."); + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + foreach (var torrentClientInfo in torrentClients) + { + var torrentClient = torrentClientInfo.Create(); + torrentClient.SetLabel( + torrentClient.GetAllTorrentHash() + .Join(topicInfoList, tc => tc.Hash, tp => tp.Hash, (tc, tp) => tp.Hash).ToArray(), + label); + num1 += new decimal(1000, 0, 0, false, 1) / torrentClients.Count(); + if (num1 <= new decimal(100)) + backgroundWorker.ReportProgress((int) num1); + } + + backgroundWorker.ReportProgress(100); + } + catch (Exception ex) + { + logger.Error("Произошла ошибка при установке пользовательских меток в торрент-клиент: " + ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show("Произошла ошибка:\r\n" + ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwUpdateCountSeedersByAllCategories(object sender, DoWorkEventArgs e) + { + logger.Info("Запущена задача на обновление информации о кол-ве сидов на раздачах..."); + var backgroundWorker = sender as BackgroundWorker; + var num = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num); + try + { + logger.Trace("\t Очищаем историю о кол-ве сидов на раздаче..."); + ClientLocalDb.Current.ClearHistoryStatus(); + var categoriesEnable = ClientLocalDb.Current.GetCategoriesEnable(); + foreach (var category in categoriesEnable) + { + logger.Trace("\t " + category.Name + "..."); + try + { + ClientLocalDb.Current.SaveStatus(RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID), + true); + } + catch (Exception ex) + { + logger.Warn("Не удалось обновить кол-во сидов по разделу \"" + category.Name + "\""); + logger.Debug(ex); + } + + num += new decimal(1000, 0, 0, false, 1) / categoriesEnable.Count; + backgroundWorker.ReportProgress((int) num); + } + + if (Settings.Current.IsUpdateStatistics) + { + logger.Trace("\t Обновление статистики..."); + ClientLocalDb.Current.UpdateStatistics(); + } + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + } + + logger.Info("Завершена задача по обновлению информации о кол-ве сидов на раздачах."); + } + + public static void bwUpdateHashFromAllTorrentClients(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + ClientLocalDb.Current.ResetFlagsTopicDownloads(); + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + foreach (var torrentClientInfo in torrentClients) + { + try + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + ClientLocalDb.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); + } + catch (Exception ex) + { + logger.Warn("Не удалось загрузить список статусов раздач из torrent-клиента \"" + + torrentClientInfo.Name + "\": \"" + ex.Message + + "\". Возможно клиент не запущен или нет доступа."); + logger.Debug(ex); + } + + num1 += new decimal(1000, 0, 0, false, 1) / torrentClients.Count; + backgroundWorker.ReportProgress((int) num1); + } + + Reports.CreateReports(); + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwUpdateHashFromTorrentClientsByCategoryUID(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + var category = e.Argument as Category; + if (category == null) + return; + logger.Info("Обновление списка хранимого из торрент-клиента (по разделу)..."); + var list = ClientLocalDb.Current.GetTorrentClients() + .Where(x => x.UID == category.TorrentClientUID).ToList(); + foreach (var torrentClientInfo in list) + { + try + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + ClientLocalDb.Current.SetTorrentClientHash(torrentClient.GetAllTorrentHash()); + } + catch (Exception ex) + { + logger.Warn("Не удалось загрузить список статусов раздач из torrent-клиента \"" + + torrentClientInfo.Name + "\": \"" + ex.Message + + "\". Возможно клиент не запущен или нет доступа."); + logger.Debug(ex); + } + + num1 += new decimal(1000, 0, 0, false, 1) / list.Count; + backgroundWorker.ReportProgress((int) num1); + } + + Reports.CreateReports(); + logger.Info("Завершена задача по обновлению списка хранимого из торрент-клиента (по разделу)."); + } + catch (Exception ex) + { + logger.Error("Произошла ошибка при обновлении списка хранимого из торрент-клиента: " + ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwUpdateTopicsByCategory(object sender, DoWorkEventArgs e) + { + var backgroundWorker = sender as BackgroundWorker; + var category = e.Argument as Category; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + var array = RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID).Select(x => x[0]).Distinct() + .ToArray(); + var intListArray = + new List[array.Length % 100 == 0 ? array.Length / 100 : array.Length / 100 + 1]; + for (var index1 = 0; index1 < array.Length; ++index1) + { + var index2 = index1 / 100; + if (intListArray[index2] == null) + intListArray[index2] = new List(); + intListArray[index2].Add(array[index1]); + } + + foreach (var intList in intListArray) + { + ClientLocalDb.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(intList.ToArray()), true); + num1 += new decimal(1000, 0, 0, false, 1) / intListArray.Length; + backgroundWorker.ReportProgress((int) num1); + } + + ClientLocalDb.Current.SaveUsers(RuTrackerOrg.Current.GetUsers(ClientLocalDb.Current.GetNoUsers())); + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + } + + public static void bwUpdateTopicsByCategories(object sender, DoWorkEventArgs e) + { + logger.Info("Запущена задача по обновлению топиков..."); + var backgroundWorker = sender as BackgroundWorker; + var categoryList = e.Argument as List; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + foreach (var category in categoryList) + { + logger.Trace("\t Обрабатывается форум \"" + category.Name + "\"..."); + try + { + var array = RuTrackerOrg.Current.GetTopicsStatus(category.CategoryID).Select(x => x[0]) + .Distinct().ToArray(); + var intListArray = + new List[array.Length % 100 == 0 ? array.Length / 100 : array.Length / 100 + 1]; + for (var index1 = 0; index1 < array.Length; ++index1) + { + var index2 = index1 / 100; + if (intListArray[index2] == null) + intListArray[index2] = new List(); + intListArray[index2].Add(array[index1]); + } + + ClientLocalDb.Current.DeleteTopicsByCategoryId(category.CategoryID); + foreach (var intList in intListArray) + { + ClientLocalDb.Current.SaveTopicInfo(RuTrackerOrg.Current.GetTopicsInfo(intList.ToArray()), + true); + num1 += new decimal(1000, 0, 0, false, 1) / (categoryList.Count * intListArray.Length); + backgroundWorker.ReportProgress((int) num1); + } + } + catch (Exception ex) + { + logger.Error("Ошибка при обновлении топиков: " + ex.Message); + logger.Debug(ex); + } + + ClientLocalDb.Current.SaveUsers(RuTrackerOrg.Current.GetUsers(ClientLocalDb.Current.GetNoUsers())); + } + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, + MessageBoxDefaultButton.Button1); + } + + logger.Info("Завершена задача по обновлению топиков."); + } + + public static void bwUpdateKeepersByAllCategories(object sender, DoWorkEventArgs e) + { + logger.Info("Запущена задача по обновлению информации о хранителях..."); + var backgroundWorker = sender as BackgroundWorker; + var num1 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num1); + try + { + ClientLocalDb.Current.ClearKeepers(); + var categories = ClientLocalDb.Current.GetCategoriesEnable().Select(x => x.CategoryID).OrderBy(x => x) + .ToArray(); + var array = ClientLocalDb.Current.GetReports(new int?()).Where(x => + { + if (x.Key.Item2 == 0 && x.Key.Item1 != 0 && !string.IsNullOrWhiteSpace(x.Value.Item1)) + return categories.Any(z => z == x.Key.Item1); + return false; + }).Select(x => + { + var strArray = x.Value.Item1.Split('='); + if (strArray.Length == 3) + return new + { + TopicID = int.Parse(strArray[2]), + CategoryID = x.Key.Item1 + }; + if (strArray.Length == 2) + return new + { + TopicID = int.Parse(strArray[1]), + CategoryID = x.Key.Item1 + }; + return new + { + TopicID = 0, + CategoryID = x.Key.Item1 + }; + }).Where(x => (uint) x.TopicID > 0U).OrderBy(x => x.CategoryID).ToArray(); + var ruTrackerOrg = new RuTrackerOrg(Settings.Current.KeeperName, Settings.Current.KeeperPass); + foreach (var data in array) + { + logger.Trace("\t" + data.CategoryID); + ClientLocalDb.Current.SaveKeepOtherKeepers(ruTrackerOrg.GetKeeps(data.TopicID, data.CategoryID)); + num1 += new decimal(1000, 0, 0, false, 1) / array.Count(); + backgroundWorker.ReportProgress((int) num1); + } + + Reports.CreateReportByRootCategories(); + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + var num2 = (int) MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, + MessageBoxDefaultButton.Button1); + } + + logger.Info("Завершена задача по обновлению информации о хранителях."); + } + + public static void bwRuningAndStopingDistributions(object sender, DoWorkEventArgs e) + { + logger.Info("Запущена задача по запуску/остановке раздач в торрент-клиентах..."); + var backgroundWorker = sender as BackgroundWorker; + var obj = e.Argument; + var num = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num); + var countSeedersBycategories = new Dictionary(); + try + { + var inner = ClientLocalDb.Current.GetTopicsByCategory(-1).Where(x => !x.IsBlackList); + foreach (var category in ClientLocalDb.Current.GetCategoriesEnable()) + if (!countSeedersBycategories.ContainsKey(category.CategoryID)) + countSeedersBycategories.Add(category.CategoryID, category.CountSeeders); + + ClientLocalDb.Current.ResetFlagsTopicDownloads(); + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + foreach (var torrentClientInfo in torrentClients) + { + try + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + { + var allTorrentHash = torrentClient.GetAllTorrentHash(); + logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + "\": " + + allTorrentHash.Count); + ClientLocalDb.Current.SetTorrentClientHash(allTorrentHash); + var list = allTorrentHash.Join(inner, c => c.Hash, a => a.Hash, (c, a) => new + { + c, a + }).Where(_param1 => _param1.c.IsRun.HasValue).Select(_param1 => new + { + _param1.a.Hash, + IsRun = _param1.c.IsRun.Value, + _param1.c.IsPause, + _param1.a.Seeders, + MaxSeeders = countSeedersBycategories.ContainsKey(_param1.a.CategoryID) + ? countSeedersBycategories[_param1.a.CategoryID] + : new int?() + }).ToList(); + var array1 = list.Where(x => + { + if (x.IsRun && x.MaxSeeders.HasValue) + return x.Seeders > x.MaxSeeders.Value + 1; + return false; + }).Select(x => x.Hash).ToArray(); + logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + + "\" которые требуется остановить: " + array1.Length + ". Останавливаем..."); + var stringListArray1 = + new List[array1.Length / 50 + (array1.Length % 50 != 0 ? 1 : 0)]; + for (var index1 = 0; index1 < array1.Length; ++index1) + { + var index2 = index1 / 50; + if (stringListArray1[index2] == null) + stringListArray1[index2] = new List(); + stringListArray1[index2].Add(array1[index1]); + } + + if (stringListArray1.Length == 0) + { + num += new decimal(1000, 0, 0, false, 1) / (2 * torrentClients.Count); + backgroundWorker.ReportProgress((int) num); + } + + foreach (var stringList in stringListArray1) + { + if (stringList != null) + torrentClient.DistributionStop(stringList); + num += new decimal(1000, 0, 0, false, 1) / + (2 * torrentClients.Count * stringListArray1.Length); + backgroundWorker.ReportProgress((int) num); + } + + var array2 = list.Where(x => + { + if ((!x.IsRun || x.IsPause) && x.MaxSeeders.HasValue) + return x.Seeders <= x.MaxSeeders.Value; + return false; + }).Select(x => x.Hash).ToArray(); + var stringListArray2 = + new List[array2.Length / 50 + (array2.Length % 50 != 0 ? 1 : 0)]; + logger.Info("\t Кол-во раздач в торрент-клиенте \"" + torrentClientInfo.Name + + "\" которые требуется запустить: " + array2.Length + ". Запускаем..."); + for (var index1 = 0; index1 < array2.Length; ++index1) + { + var index2 = index1 / 50; + if (stringListArray2[index2] == null) + stringListArray2[index2] = new List(); + stringListArray2[index2].Add(array2[index1]); + } + + if (stringListArray2.Length == 0) + { + num += new decimal(1000, 0, 0, false, 1) / (2 * torrentClients.Count); + backgroundWorker.ReportProgress((int) num); + } + + foreach (var stringList in stringListArray2) + { + if (stringList != null) + torrentClient.DistributionStart(stringList); + num += new decimal(1000, 0, 0, false, 1) / + (2 * torrentClients.Count * stringListArray2.Length); + backgroundWorker.ReportProgress((int) num); + } + } + else + { + num += new decimal(1000, 0, 0, false, 1) / torrentClients.Count; + } + + backgroundWorker.ReportProgress((int) num); + } + catch (Exception ex) + { + logger.Warn("Не удалось запустить/остановить раздачи на клиенте \"" + torrentClientInfo.Name + + "\": " + ex.Message); + logger.Debug(ex); + num += new decimal(1000, 0, 0, false, 1) / torrentClients.Count; + } + + backgroundWorker.ReportProgress((int) num); + } + + logger.Info("Строим отчеты о хранимом..."); + Reports.CreateReports(); + logger.Info("Отчеты о хранимом построены."); + } + catch (Exception ex) + { + logger.Warn("Произошла критическая ошибка при запуске/остановке раздач"); + logger.Debug(ex); + } + + logger.Info("Завершена задача по запуску/остановке раздач в торрент-клиентах."); + logger.Debug(string.Format("Размер ОЗУ 1: {0}", GC.GetTotalMemory(false))); + GC.Collect(2); + logger.Debug(string.Format("Размер ОЗУ 2: {0}", GC.GetTotalMemory(false))); + } + + public static void bwCreateReportsTorrentClients(object sender, DoWorkEventArgs e) + { + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + var inner = ClientLocalDb.Current.GetTopicsByCategory(-1).Where(x => !x.IsBlackList); + logger.Info("Строим отчет о статистике в торрент-клиенте..."); + var stringBuilder = new StringBuilder(); + var dictionary = + ClientLocalDb.Current.GetCategories().ToDictionary(x => x.CategoryID, x => x); + var num1 = Math.Max(dictionary.Count == 0 ? 20 : dictionary.Values.Max(x => x.FullName.Length), + torrentClients.Count == 0 ? 20 : torrentClients.Max(x => x.Name.Length)); + var empty = string.Empty; + for (var index = 0; index < num1; ++index) + empty += "*"; + var backgroundWorker = sender as BackgroundWorker; + var num2 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num2); + foreach (var torrentClientInfo in torrentClients) + { + logger.Debug("\t" + torrentClientInfo.Name + "..."); + try + { + stringBuilder.AppendLine(empty); + stringBuilder.AppendFormat("*\t{0}\r\n", torrentClientInfo.Name); + stringBuilder.AppendLine(empty); + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + { + var array1 = torrentClient.GetAllTorrentHash().GroupJoin(inner, t => t.Hash, b => b.Hash, + (t, bt) => new + { + t, bt + }).SelectMany(_param1 => _param1.bt.DefaultIfEmpty(), (_param1, b) => + { + var num3 = b != null ? b.CategoryID : -1; + var size = _param1.t.Size; + var isRun = _param1.t.IsRun; + int num4; + if (!isRun.HasValue) + { + num4 = -1; + } + else + { + isRun = _param1.t.IsRun; + num4 = isRun.Value ? 1 : 0; + } + + var num5 = _param1.t.IsPause ? 1 : 0; + var num6 = b == null ? -1 : b.Seeders; + return new + { + CategoryID = num3, + Size = size, + IsRun = num4, + IsPause = num5 != 0, + Seeders = num6 + }; + }).GroupBy(x => new + { + x.CategoryID, + x.IsRun, + x.IsPause, + x.Seeders + }).Select(x => new + { + x.Key.CategoryID, + x.Key.IsRun, + x.Key.IsPause, + Size = x.Sum(y => y.Size), + Count = x.Count(), + x.Key.Seeders + }).ToArray(); + stringBuilder.AppendFormat("\tВсего:\t\t{0,6} шт. ({1})\r\n", array1.Sum(x => x.Count), + TopicInfo.sizeToString(array1.Sum(x => x.Size))); + stringBuilder.AppendFormat("\tРаздаются:\t{0,6} шт. ({1})\r\n", + array1.Where(x => x.IsRun == 1).Sum(x => x.Count), + TopicInfo.sizeToString(array1.Where(x => x.IsRun == 1).Sum(x => x.Size))); + stringBuilder.AppendFormat("\tОстановлены:\t{0,6} шт. ({1})\r\n", + array1.Where(x => x.IsRun == 0).Sum(x => x.Count), + TopicInfo.sizeToString(array1.Where(x => x.IsRun == 0).Sum(x => x.Size))); + stringBuilder.AppendFormat("\tПрочие:\t\t{0,6} шт. ({1})\r\n", + array1.Where(x => x.IsRun == -1).Sum(x => x.Count), + TopicInfo.sizeToString(array1.Where(x => x.IsRun == -1).Sum(x => x.Size))); + stringBuilder.AppendFormat("\tНеизвестные:\t{0,6} шт. ({1})\r\n", + array1.Where(x => x.CategoryID == -1).Sum(x => x.Count), + TopicInfo.sizeToString(array1.Where(x => x.CategoryID == -1).Sum(x => x.Size))); + stringBuilder.AppendLine(); + stringBuilder.AppendFormat("\tПо кол-ву сидов:\r\n"); + foreach (var data in array1.GroupBy(x => x.Seeders).Select(x => new + { + Seeders = x.Key, + Count = x.Sum(z => z.Count), + Size = x.Sum(z => z.Size) + }).OrderBy(x => x.Seeders)) + stringBuilder.AppendFormat("\t{2}:\t\t{0,5} шт. ({1})\r\n", data.Count, + TopicInfo.sizeToString(data.Size), data.Seeders); + stringBuilder.AppendLine(); + foreach (var num3 in array1.Select(x => x.CategoryID).Distinct().OrderBy(x => x).ToArray()) + { + var c = num3; + var array2 = array1.Where(x => x.CategoryID == c).ToArray(); + var str = "Неизвестные"; + if (dictionary.ContainsKey(c)) + str = dictionary[c].FullName; + stringBuilder.AppendFormat("{0}:\r\n", str); + stringBuilder.AppendFormat("\tВсего:\t\t{0,5} шт. ({1})\r\n", array2.Sum(x => x.Count), + TopicInfo.sizeToString(array2.Sum(x => x.Size))); + stringBuilder.AppendFormat("\tРаздаются:\t{0,5} шт. ({1})\r\n", + array2.Where(x => x.IsRun == 1).Sum(x => x.Count), + TopicInfo.sizeToString(array2.Where(x => x.IsRun == 1).Sum(x => x.Size))); + stringBuilder.AppendFormat("\tОстановлены:\t{0,5} шт. ({1})\r\n", + array2.Where(x => x.IsRun == 0).Sum(x => x.Count), + TopicInfo.sizeToString(array2.Where(x => x.IsRun == 0).Sum(x => x.Size))); + stringBuilder.AppendFormat("\tПрочие:\t\t{0,5} шт. ({1})\r\n", + array2.Where(x => x.IsRun == -1).Sum(x => x.Count), + TopicInfo.sizeToString(array2.Where(x => x.IsRun == -1).Sum(x => x.Size))); + } + + stringBuilder.AppendLine(); + } + } + catch (Exception ex) + { + stringBuilder.AppendFormat("Ошибка: {0}\r\n\r\n\r\n", ex.Message); + } + + stringBuilder.AppendLine(); + num2 += new decimal(1000, 0, 0, false, 1) / torrentClients.Count(); + if (num2 <= new decimal(100)) + backgroundWorker.ReportProgress((int) num2); + } + + var reports = new Dictionary>(); + reports.Add(0, new Dictionary()); + reports[0].Add(1, stringBuilder.ToString()); + try + { + ClientLocalDb.Current.SaveReports(reports); + logger.Info("Отчет о статистике в торрент-клиенте построен."); + } + catch (Exception ex) + { + logger.Error("Произошла ошибка при сохранении отчета в базу данных: " + ex.Message); + logger.Trace(ex.StackTrace); + } + } + + public static void bwCreateUnknownTorrentsReport(object sender, DoWorkEventArgs e) + { + var torrentClients = ClientLocalDb.Current.GetTorrentClients(); + var inner = ClientLocalDb.Current.GetTopicsByCategory(-1).Where(x => !x.IsBlackList); + logger.Info("Строим отчет о статистике в торрент-клиенте..."); + var stringBuilder = new StringBuilder(); + var dictionary = + ClientLocalDb.Current.GetCategories().ToDictionary(x => x.CategoryID, x => x); + var num1 = Math.Max(dictionary.Count == 0 ? 20 : dictionary.Values.Max(x => x.FullName.Length), + torrentClients.Count == 0 ? 20 : torrentClients.Max(x => x.Name.Length)); + var empty = string.Empty; + for (var index = 0; index < num1; ++index) + empty += "*"; + var backgroundWorker = sender as BackgroundWorker; + var num2 = new decimal(0, 0, 0, false, 1); + backgroundWorker.ReportProgress((int) num2); + var listUnknown = new StringBuilder(); + listUnknown.AppendLine("Клиент;Метка;Торрент;Размер"); + foreach (var torrentClientInfo in torrentClients) + { + logger.Debug("\t" + torrentClientInfo.Name + "..."); + try + { + var torrentClient = torrentClientInfo.Create(); + if (torrentClient != null) + { + var array1 = torrentClient.GetAllTorrentHash().GroupJoin(inner, t => t.Hash, b => b.Hash, + (t, bt) => new + { + t, bt + }).SelectMany(_param1 => _param1.bt.DefaultIfEmpty(), (_param1, b) => + { + var num3 = b != null ? b.CategoryID : -1; + var size = _param1.t.Size; + var isRun = _param1.t.IsRun; + int num4; + if (!isRun.HasValue) + { + num4 = -1; + } + else + { + isRun = _param1.t.IsRun; + num4 = isRun.Value ? 1 : 0; + } + + var num5 = _param1.t.IsPause ? 1 : 0; + var num6 = b == null ? -1 : b.Seeders; + return new + { + CategoryID = num3, + Name = _param1.t.TorrentName, + Size = size, + IsRun = num4, + IsPause = num5 != 0, + Seeders = num6, + _param1.t.Label + }; + }).GroupBy(x => new + { + x.CategoryID, + x.Name, + x.IsRun, + x.IsPause, + x.Seeders, + x.Label + }).Select(x => new + { + x.Key.CategoryID, + x.Key.Name, + x.Key.IsRun, + x.Key.IsPause, + Size = x.Sum(y => y.Size), + Count = x.Count(), + x.Key.Seeders, + x.Key.Label + }).ToArray(); + var countUnknown = array1.Where(x => x.CategoryID == -1).Sum(x => x.Count); + foreach (var info in array1.Where(x => x.CategoryID == -1).ToList()) + listUnknown.AppendLine(string.Join(";", torrentClientInfo.Name, info.Label, info.Name, + TopicInfo.sizeToString(info.Size))); + } + } + catch (Exception ex) + { + listUnknown.AppendFormat("Ошибка: {0}\r\n\r\n\r\n", ex.Message); + } + + num2 += new decimal(1000, 0, 0, false, 1) / torrentClients.Count(); + if (num2 <= new decimal(100)) + backgroundWorker.ReportProgress((int) num2); + } + + var saveFileDialog = new SaveFileDialog(); + saveFileDialog.AddExtension = true; + saveFileDialog.DefaultExt = "csv"; + saveFileDialog.Filter = @".csv|CSV файл|.txt|Текстовый документ"; + saveFileDialog.OverwritePrompt = true; + var form = (MainForm) e.Argument; + form.Invoke((MethodInvoker) delegate + { + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + var file = saveFileDialog.OpenFile(); + var writer = new StreamWriter(file, Encoding.UTF8); + writer.Write(listUnknown.ToString()); + writer.Flush(); + file.Close(); + } + }); + } + + public static void bwSendReports(object sender, DoWorkEventArgs e) + { + logger.Info("Запущена задача на отправку отчетов на форум...."); + var num1 = new decimal(0, 0, 0, false, 1); + var backgroundWorker = sender as BackgroundWorker; + var array = ClientLocalDb.Current.GetReports(new int?()) + .Where(x => !string.IsNullOrWhiteSpace(x.Value.Item1)).OrderBy(x => x.Key.Item1).Select(x => x.Value) + .Where(x => x.Item1.Split('=').Length == 3).ToArray(); + if (array.Where(x => !string.IsNullOrWhiteSpace(x.Item1)).Count() == 0) + { + var num2 = (int) MessageBox.Show("Нет ни одного отчета c указанным URL для отправки на форум"); + } + else + { + foreach (var tuple in array.Where(x => !string.IsNullOrWhiteSpace(x.Item1))) + { + logger.Info(tuple.Item1); + try + { + RuTrackerOrg.Current.SendReport(tuple.Item1, tuple.Item2); + } + catch (Exception ex) + { + logger.Error(ex.Message); + logger.Debug(ex); + var num3 = (int) MessageBox.Show("Произошла ошибка при отправке отчетов:\r\n" + ex.Message, + "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); + } + + num1 += new decimal(1000, 0, 0, false, 1) / array.Length; + backgroundWorker.ReportProgress((int) num1); + } + + logger.Info("Завершена задача на отправку отчетов на форум."); + } + } + } +} \ No newline at end of file diff --git a/TLO/hdd.ico b/TLO/hdd.ico new file mode 100644 index 0000000..4cdc97a Binary files /dev/null and b/TLO/hdd.ico differ diff --git a/TLO/hdd.jpg b/TLO/hdd.jpg new file mode 100644 index 0000000..670c06b Binary files /dev/null and b/TLO/hdd.jpg differ diff --git a/TLO/hdd.png b/TLO/hdd.png new file mode 100644 index 0000000..4f70849 Binary files /dev/null and b/TLO/hdd.png differ diff --git a/TLO/hdd_128x128.ico b/TLO/hdd_128x128.ico new file mode 100644 index 0000000..39c14ed Binary files /dev/null and b/TLO/hdd_128x128.ico differ diff --git a/TLO/hdd_16x16.ico b/TLO/hdd_16x16.ico new file mode 100644 index 0000000..bf5e095 Binary files /dev/null and b/TLO/hdd_16x16.ico differ diff --git a/TLO/hdd_256x256.ico b/TLO/hdd_256x256.ico new file mode 100644 index 0000000..c6d9467 Binary files /dev/null and b/TLO/hdd_256x256.ico differ diff --git a/TLO/hdd_32x32.ico b/TLO/hdd_32x32.ico new file mode 100644 index 0000000..d035d61 Binary files /dev/null and b/TLO/hdd_32x32.ico differ diff --git a/TLO/hdd_64x64.ico b/TLO/hdd_64x64.ico new file mode 100644 index 0000000..053d504 Binary files /dev/null and b/TLO/hdd_64x64.ico differ diff --git a/Resources/hdd.ico b/TLO/hdd_old.ico similarity index 100% rename from Resources/hdd.ico rename to TLO/hdd_old.ico diff --git a/TLO/hdd_small.ico b/TLO/hdd_small.ico new file mode 100644 index 0000000..589bb09 Binary files /dev/null and b/TLO/hdd_small.ico differ diff --git a/TLO/packages.config b/TLO/packages.config new file mode 100644 index 0000000..c25d3c7 --- /dev/null +++ b/TLO/packages.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hdd.ico b/hdd.ico deleted file mode 100644 index 57314d5..0000000 Binary files a/hdd.ico and /dev/null differ diff --git a/lib/NLog.dll b/lib/NLog.dll deleted file mode 100644 index cad50cc..0000000 Binary files a/lib/NLog.dll and /dev/null differ diff --git a/lib/Newtonsoft.Json.dll b/lib/Newtonsoft.Json.dll deleted file mode 100644 index ae725c4..0000000 Binary files a/lib/Newtonsoft.Json.dll and /dev/null differ diff --git a/lib/System.Data.SQLite.dll b/lib/System.Data.SQLite.dll deleted file mode 100644 index 3ac522b..0000000 Binary files a/lib/System.Data.SQLite.dll and /dev/null differ diff --git a/packages.config b/packages.config deleted file mode 100644 index e300e93..0000000 --- a/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/x64/SQLite.Interop.dll b/x64/SQLite.Interop.dll deleted file mode 100644 index b9be66f..0000000 Binary files a/x64/SQLite.Interop.dll and /dev/null differ diff --git a/x86/SQLite.Interop.dll b/x86/SQLite.Interop.dll deleted file mode 100644 index c38f0d3..0000000 Binary files a/x86/SQLite.Interop.dll and /dev/null differ