From adbebc37ecbf9c5204bf87c0d22b9ba3e4e9d1c6 Mon Sep 17 00:00:00 2001 From: timerix Date: Wed, 22 Feb 2023 03:52:43 +0600 Subject: [PATCH] 000 --- .gitignore | 5 + .../.idea/.gitignore | 10 ++ .../.idea/discord.xml | 7 ++ .../.idea/encodings.xml | 6 + .../.idea/indexLayout.xml | 8 ++ .../.idea/vcs.xml | 6 + Config.cs | 57 +++++++++ InstaFollowersOverseer.csproj | 30 +++++ InstaFollowersOverseer.sln | 34 +++++ InstagramObservableParams.cs | 35 ++++++ Program.cs | 118 ++++++++++++++++++ SharedData.cs | 16 +++ UserSettings.cs | 114 +++++++++++++++++ resources/config-example.dtsod | 4 + resources/user-settings-example.dtsod | 11 ++ 15 files changed, 461 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.idea.InstaFollowersOverseer/.idea/.gitignore create mode 100644 .idea/.idea.InstaFollowersOverseer/.idea/discord.xml create mode 100644 .idea/.idea.InstaFollowersOverseer/.idea/encodings.xml create mode 100644 .idea/.idea.InstaFollowersOverseer/.idea/indexLayout.xml create mode 100644 .idea/.idea.InstaFollowersOverseer/.idea/vcs.xml create mode 100644 Config.cs create mode 100644 InstaFollowersOverseer.csproj create mode 100644 InstaFollowersOverseer.sln create mode 100644 InstagramObservableParams.cs create mode 100644 Program.cs create mode 100644 SharedData.cs create mode 100644 UserSettings.cs create mode 100644 resources/config-example.dtsod create mode 100644 resources/user-settings-example.dtsod diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..add57be --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ \ No newline at end of file diff --git a/.idea/.idea.InstaFollowersOverseer/.idea/.gitignore b/.idea/.idea.InstaFollowersOverseer/.idea/.gitignore new file mode 100644 index 0000000..f13e0eb --- /dev/null +++ b/.idea/.idea.InstaFollowersOverseer/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/projectSettingsUpdater.xml +/.idea.InstaFollowersOverseer.iml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/.idea.InstaFollowersOverseer/.idea/discord.xml b/.idea/.idea.InstaFollowersOverseer/.idea/discord.xml new file mode 100644 index 0000000..30bab2a --- /dev/null +++ b/.idea/.idea.InstaFollowersOverseer/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.InstaFollowersOverseer/.idea/encodings.xml b/.idea/.idea.InstaFollowersOverseer/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/.idea.InstaFollowersOverseer/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.InstaFollowersOverseer/.idea/indexLayout.xml b/.idea/.idea.InstaFollowersOverseer/.idea/indexLayout.xml new file mode 100644 index 0000000..f5a863a --- /dev/null +++ b/.idea/.idea.InstaFollowersOverseer/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.InstaFollowersOverseer/.idea/vcs.xml b/.idea/.idea.InstaFollowersOverseer/.idea/vcs.xml new file mode 100644 index 0000000..c8397c9 --- /dev/null +++ b/.idea/.idea.InstaFollowersOverseer/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Config.cs b/Config.cs new file mode 100644 index 0000000..762dd7f --- /dev/null +++ b/Config.cs @@ -0,0 +1,57 @@ +namespace InstaFollowersOverseer; + +public class Config +{ + + private const string config_file="config.dtsod"; + private const string config_example_file="config-example.dtsod"; + + public string botToken; + public string instagramLogin; + public string instagramPassword; + + public Config(DtsodV23 configDtsod) + { + botToken = configDtsod[nameof(botToken)]; + instagramLogin = configDtsod[nameof(instagramLogin)]; + instagramPassword = configDtsod[nameof(instagramPassword)]; + } + + public static Config ReadFromFile() + { + if (!File.Exists(config_file)) + { + EmbeddedResources.CopyToFile( + $"{EmbeddedResourcesPrefix}.{config_example_file}", + config_example_file); + throw new Exception($"File {config_file} doesnt exist. You have create config. See {config_example_file}"); + } + + return new Config(new DtsodV23(File.ReadAllText(config_file))); + } + + public DtsodV23 ToDtsod() + { + var d = new DtsodV23 + { + { nameof(botToken), botToken }, + { nameof(instagramLogin), instagramLogin }, + { nameof(instagramLogin), instagramLogin } + }; + return d; + } + + public override string ToString() => ToDtsod().ToString(); + + public void SaveToFile() + { + File.Copy(config_file, + $"backups/{config_file}.old-"+ + "{DateTime.Now.ToString(MyTimeFormat.ForFileNames)}", + true); + + File.OpenWrite(config_file) + .FluentWriteString("#DtsodV23\n") + .WriteString(ToDtsod().ToString()); + } +} \ No newline at end of file diff --git a/InstaFollowersOverseer.csproj b/InstaFollowersOverseer.csproj new file mode 100644 index 0000000..06a38b0 --- /dev/null +++ b/InstaFollowersOverseer.csproj @@ -0,0 +1,30 @@ + + + + Exe + net6.0 + disable + enable + preview + + + + + + + + + + + + + + + + + + + + + + diff --git a/InstaFollowersOverseer.sln b/InstaFollowersOverseer.sln new file mode 100644 index 0000000..e9cb15f --- /dev/null +++ b/InstaFollowersOverseer.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstaFollowersOverseer", "InstaFollowersOverseer.csproj", "{719B7EEE-E269-40FF-8C88-A2AD72DDEBC0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "..\DTLib\DTLib\DTLib.csproj", "{16DB4211-CCA7-403D-AE66-10A02FD09780}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Dtsod", "..\DTLib\DTLib.Dtsod\DTLib.Dtsod.csproj", "{C1425F7B-776D-45C5-B282-50892241B6E5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Logging", "..\DTLib\DTLib.Logging\DTLib.Logging.csproj", "{B823331A-924B-4F5B-9070-BFFA93DE9E62}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {719B7EEE-E269-40FF-8C88-A2AD72DDEBC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {719B7EEE-E269-40FF-8C88-A2AD72DDEBC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {719B7EEE-E269-40FF-8C88-A2AD72DDEBC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {719B7EEE-E269-40FF-8C88-A2AD72DDEBC0}.Release|Any CPU.Build.0 = Release|Any CPU + {16DB4211-CCA7-403D-AE66-10A02FD09780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16DB4211-CCA7-403D-AE66-10A02FD09780}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16DB4211-CCA7-403D-AE66-10A02FD09780}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16DB4211-CCA7-403D-AE66-10A02FD09780}.Release|Any CPU.Build.0 = Release|Any CPU + {C1425F7B-776D-45C5-B282-50892241B6E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1425F7B-776D-45C5-B282-50892241B6E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1425F7B-776D-45C5-B282-50892241B6E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1425F7B-776D-45C5-B282-50892241B6E5}.Release|Any CPU.Build.0 = Release|Any CPU + {B823331A-924B-4F5B-9070-BFFA93DE9E62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B823331A-924B-4F5B-9070-BFFA93DE9E62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B823331A-924B-4F5B-9070-BFFA93DE9E62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B823331A-924B-4F5B-9070-BFFA93DE9E62}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/InstagramObservableParams.cs b/InstagramObservableParams.cs new file mode 100644 index 0000000..6edcd8f --- /dev/null +++ b/InstagramObservableParams.cs @@ -0,0 +1,35 @@ +namespace InstaFollowersOverseer; + +public class InstagramObservableParams +{ + public string instagramUserId; + public bool notifyOnFollowing=true; + public bool notifyOnUnfollowing=true; + + public InstagramObservableParams(string instaUserId) + { + instagramUserId = instaUserId; + } + + public InstagramObservableParams(DtsodV23 _overseeParams) + { + instagramUserId = _overseeParams["instagramUserId"]; + if (_overseeParams.TryGetValue("notifyOnFollowing", out var _notifyOnFollowing)) + notifyOnFollowing = _notifyOnFollowing; + if (_overseeParams.TryGetValue("notifyOnUnfollowing", out var _notifyOnUnfollowing)) + notifyOnUnfollowing = _notifyOnUnfollowing; + } + + public DtsodV23 ToDtsod() + { + var d = new DtsodV23(); + d.Add(nameof(instagramUserId), instagramUserId); + if(!notifyOnFollowing) + d.Add(nameof(notifyOnFollowing), false); + if(!notifyOnUnfollowing) + d.Add(nameof(notifyOnFollowing), false); + return d; + } + + public override string ToString() => ToDtsod().ToString(); +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..4dabd70 --- /dev/null +++ b/Program.cs @@ -0,0 +1,118 @@ +global using System; +global using System.Threading.Tasks; +global using System.Linq; +global using System.Collections.Generic; +global using DTLib.Filesystem; +global using DTLib.Extensions; +global using DTLib.Dtsod; +global using DTLib.Logging.New; +global using File = DTLib.Filesystem.File; +global using Directory = DTLib.Filesystem.Directory; +global using Path = DTLib.Filesystem.Path; +global using static InstaFollowersOverseer.SharedData; +using System.Net.Http; +using System.Text; +using System.Threading; +using Telegram.Bot; +using Telegram.Bot.Polling; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace InstaFollowersOverseer; + +static class Program +{ + static void Main() + { + Console.InputEncoding=Encoding.UTF8; + Console.OutputEncoding=Encoding.UTF8; + DTLibInternalLogging.SetLogger(MainLogger.ParentLogger); + try + { + config = Config.ReadFromFile(); + userSettings = UserSettings.ReadFromFile(); + + CancellationTokenSource mainCancel = new CancellationTokenSource(); + Console.CancelKeyPress += (_, e) => + { + mainCancel.Cancel(); + Thread.Sleep(1000); + MainLogger.LogInfo("all have cancelled"); + e.Cancel = false; + }; + + var bot = new TelegramBotClient(config.botToken, new HttpClient()); + var receiverOptions = new ReceiverOptions + { + AllowedUpdates = { }, // receive all update types + + }; + bot.StartReceiving(BotApiUpdateHandler, BotApiExceptionHandler, receiverOptions, mainCancel.Token); + + Task.Delay(-1, mainCancel.Token).GetAwaiter().GetResult(); + Thread.Sleep(1000); + } + catch (Exception ex) + { + MainLogger.LogError(ex); + } + Console.ResetColor(); + } + + private static ContextLogger botLogger = new ContextLogger("bot", MainLogger.ParentLogger); + + static async Task BotApiUpdateHandler(ITelegramBotClient bot, Update update, CancellationToken cls) + { + try + { + switch (update.Type) + { + case UpdateType.Message: + { + var message = update.Message!; + if (message.Text!.StartsWith('/')) + { + botLogger.LogInfo($"user {message.Chat.Id} sent command {message.Text}"); + var spl = message.Text.SplitToList(' '); + string command = spl[0].Substring(1); + spl.RemoveAt(0); + string[] args = spl.ToArray(); + switch (command) + { + case "start": + await bot.SendTextMessageAsync(message.Chat, "hi"); + break; + case "oversee": + break; + // default: + // throw new BotCommandException(command, args); + } + } + else botLogger.LogDebug($"message recieved: {message.Text}"); + + break; + } /* + case UpdateType.EditedMessage: + break; + case UpdateType.InlineQuery: + break; + case UpdateType.ChosenInlineResult: + break; + case UpdateType.CallbackQuery: + break;*/ + default: + botLogger.LogWarn($"unknown update type: {update.Type}"); + break; + } + } + catch (Exception ex) + { + botLogger.LogWarn("UpdateHandler", ex); + } + } + static Task BotApiExceptionHandler(ITelegramBotClient bot, Exception ex, CancellationToken cls) + { + botLogger.LogError(ex); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/SharedData.cs b/SharedData.cs new file mode 100644 index 0000000..f45d423 --- /dev/null +++ b/SharedData.cs @@ -0,0 +1,16 @@ +namespace InstaFollowersOverseer; + +public static class SharedData +{ + internal const string EmbeddedResourcesPrefix = "InstaFollowersOverseer.resources"; + +#nullable disable + internal static Config config; + internal static UserSettings userSettings; +#nullable enable + + public static readonly ContextLogger MainLogger = new ContextLogger("main",new CompositeLogger( + new ConsoleLogger(), + new FileLogger("logs","InstaFollowersOverseer")) + ); +} \ No newline at end of file diff --git a/UserSettings.cs b/UserSettings.cs new file mode 100644 index 0000000..914e87a --- /dev/null +++ b/UserSettings.cs @@ -0,0 +1,114 @@ +namespace InstaFollowersOverseer; + +public class UserSettings +{ + private const string user_settings_file="user-settings.dtsod"; + private const string user_settings_example_file="user-settings-example.dtsod"; + + private Dictionary> userSettings=new(); + + private UserSettings() + { + + } + + public UserSettings(DtsodV23 _userSettings) + { + try + { + foreach (var uset in _userSettings) + { + string telegramUserId = uset.Key; + + List oparams = new List(); + foreach (DtsodV23 _overseeParams in uset.Value) + oparams.Add(new InstagramObservableParams(_overseeParams)); + + userSettings.Add(telegramUserId, oparams); + } + } + catch (Exception ex) + { + throw new Exception($"your {user_settings_file} format is invalid\n" + + $"See {user_settings_example_file}", innerException:ex); + } + } + + public static UserSettings ReadFromFile() + { + EmbeddedResources.CopyToFile( + $"{EmbeddedResourcesPrefix}.{user_settings_example_file}", + user_settings_example_file); + + if (File.Exists(user_settings_file)) + return new UserSettings(new DtsodV23(File.ReadAllText(user_settings_file))); + + MainLogger.LogWarn($"file {user_settings_file} doesnt exist, creating new"); + File.WriteAllText(user_settings_file,"#DtsodV23\n"); + return new UserSettings(); + } + + public DtsodV23 ToDtsod() + { + var b = new DtsodV23(); + foreach (var userS in userSettings) + b.Add(userS.Key, + userS.Value.Select(iop => + iop.ToDtsod() + ).ToList()); + return b; + } + + public override string ToString() => ToDtsod().ToString(); + + public void SaveToFile() + { + File.Copy(user_settings_file, + $"backups/{user_settings_file}.old-"+ + "{DateTime.Now.ToString(MyTimeFormat.ForFileNames)}", + true); + + File.OpenWrite(user_settings_file) + .FluentWriteString("#DtsodV23\n") + .WriteString(ToDtsod().ToString()); + } + + public List Get(string telegramUserId) + { + if (!userSettings.TryGetValue(telegramUserId, out var overseeParams)) + throw new Exception($"there is no settings for user {telegramUserId}"); + return overseeParams; + } + + public void AddOrSet(string telegramUserId, InstagramObservableParams instagramObservableParams) + { + // Add + // doesnt contain settings for telegramUserId + if (!userSettings.TryGetValue(telegramUserId, out var thisUserSettings)) + { + userSettings.Add(telegramUserId, new (){ instagramObservableParams }); + return; + } + + // Set + // settings for telegramUserId contain InstagramObservableParams with instagramObservableParams.instagramUserId + for (var i = 0; i < thisUserSettings.Count; i++) + { + if (thisUserSettings[i].instagramUserId == instagramObservableParams.instagramUserId) + { + thisUserSettings[i] = instagramObservableParams; + return; + } + } + + // Add + // doesnt contain InstagramObservableParams with instagramObservableParams.instagramUserId + thisUserSettings.Add(instagramObservableParams); + } + + public void AddOrSet(string telegramUserId, IEnumerable instagramObservableParams) + { + foreach (var p in instagramObservableParams) + AddOrSet(telegramUserId, p); + } +} \ No newline at end of file diff --git a/resources/config-example.dtsod b/resources/config-example.dtsod new file mode 100644 index 0000000..d1c4378 --- /dev/null +++ b/resources/config-example.dtsod @@ -0,0 +1,4 @@ +#DtsodV23 +botToken:"19815858:aAjfawIAHAWw4_kAkg321"; +instagramLogin:"aboba"; +instagramPassword:"01234567"; diff --git a/resources/user-settings-example.dtsod b/resources/user-settings-example.dtsod new file mode 100644 index 0000000..af86d2b --- /dev/null +++ b/resources/user-settings-example.dtsod @@ -0,0 +1,11 @@ +#DtsodV23 + +telegramUserId: [ + { + instagramUserId: "taldybayeff"; + # optional, default: true + notifyOnFollowing: true; + # optional, default: true + notifyOnUnfollowing: true; + } +];