commit adbebc37ecbf9c5204bf87c0d22b9ba3e4e9d1c6 Author: timerix Date: Wed Feb 22 03:52:43 2023 +0600 000 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; + } +];