/// <summary> /// Method that reads in the 'mentions.txt' delimited file and adds them to the passed in StringBuilder /// </summary> /// <param name="sb"></param> /// <param name="memePath"></param> private static void AddMentions(StringBuilder sb, CampaignConfig config) { int mentionsCount = 1; // Try and keep under the spammeradar, only 1 per tweet Random rnd = new Random(); if (config.Mentions.Count > 0) { // get a random set of mentions for (int eye = 0; eye < mentionsCount; eye++) { bool ok = false; int count = 0; while (!ok) { int id = rnd.Next(0, config.Mentions.Count); string mention = config.Mentions[id]; //Dont add a duplicate if (!sb.ToString().Contains(mention, StringComparison.InvariantCulture)) { sb.Append(String.Format(".{0} ", mention)); ok = true; } // Bail if we've tried everything twice if (count == (mentionsCount * 2)) { return; } count++; } } } }
/// <summary>Method that reads in the 'hashtags.txt' delimited file and adds them to the passed in StringBuilder</summary> /// <param name="sb"></param> /// <param name="memePath"></param> /// <param name="addDefaultHashtags"></param> private static void AddHashtags(StringBuilder sb, string memePath, bool addDefaultHashtags) { // Read in a new CampaignConfig each time se we can check for campaign updates while we're running CampaignConfig config = GetCampaignConfig(memePath); List <string> currentTags = new List <string>(); int hashtagCount = config.HashTagCount; Random rnd = new Random(); if ((addDefaultHashtags) && (config.DefaultHashtags.Count > 0)) { config.DefaultHashtags.ForEach(h => { sb.Append(String.Format("{0} ", h)); currentTags.Add(h); }); } if (config.Hashtags.Count.Equals(0)) { config.Hashtags = new List <string>() { "MAGA", "Trump2020", "KAG" } } ; // Nothing to read so MAGA if (config.Hashtags.Count > 0) { // get a random set of hashtags for (int eye = 0; eye < hashtagCount; eye++) { bool ok = false; int count = 0; while (!ok) { int id = rnd.Next(0, config.Hashtags.Count); string hash = config.Hashtags[id]; //Dont add a duplicate if (!sb.ToString().Contains(hash, StringComparison.InvariantCulture)) { sb.Append(String.Format("{0} ", hash)); currentTags.Add(hash); ok = true; } // Bail if we've tried everything twice if (count == (hashtagCount * 2)) { return; } count++; } } } //Output currentTags.ForEach(h => Console.Write("{0} ", h)); }
/// <summary> /// Util method to check and see if we need to upgrade the CampaignConfig files. Saves a new migrated CampaignConfig.json if needed /// </summary> /// <param name="memePath"></param> private static CampaignConfig GetCampaignConfig(string memePath) { string path = String.Format(@"{0}\hashtags\CampaignConfig.json", memePath); CampaignConfig config = new CampaignConfig(); // Try and read in the new CampaignConfig.json, upgrade if we need to if (!File.Exists(path)) { //Read in the old vals and transfer! string path1 = String.Format(@"{0}\hashtags\hashtags.txt", memePath); string[] sep = new string[] { "#" }; List <string> list = ReadListFromFile(path1, sep); //prepend each with the sep and add to the config list.ForEach(s => config.Hashtags.Add(String.Format("{0}{1}", sep[0], s))); path1 = String.Format(@"{0}\hashtags\mentions.txt", memePath); sep = new string[] { "@" }; list = ReadListFromFile(path, sep); list.ForEach(s => config.Mentions.Add(String.Format("{0}{1}", sep[0], s))); //Set the vals of the things we want to be able to override per campaign config.DefaultHashtags = Program.CannonCfg.DefaultHashtags; config.HashTagCount = Program.CannonCfg.HashTagCount; config.MaximumDelay = Program.CannonCfg.MaximumDelay; config.MinimumDelay = Program.CannonCfg.MinimumDelay; } else { config = FileHelper.ReadJSONObjectFromFile(path).ToObject <CampaignConfig>(); } // Bring over the defaults from Program.CannonConfig if we need to if (config.DefaultHashtags.Count.Equals(0)) { config.DefaultHashtags = Program.CannonCfg.DefaultHashtags; } // Keep everything up to date FileHelper.WriteJSONToFile <CampaignConfig>(path, config); return(config); }
private static void Fire(string path, bool addDefaultHashtags, bool addPings) { List <string> hashtags = new List <string>(); List <string> existingFileNames = new List <string>(); List <string> postedFileNames = new List <string>(); List <string> imageFileTypes = new List <string>() { ".jpg", ".jpeg", ".gif", ".png" }; Random rnd = new Random(); string jsonpath = String.Format(@"{0}\hashtags\filenames.json", path); //TODO Could monitor for a change? postedFileNames = FileHelper.ReadJSONFromFile(jsonpath).ToObject <List <string> >().ToList(); existingFileNames = Directory.EnumerateFiles(path) .Where(n => !postedFileNames.Contains(n)) // Don't post anything we've already posted .Where(n => imageFileTypes.Any(ext => ext == Path.GetExtension(n).ToLower())) // filter by image ext .OrderBy(n => Guid.NewGuid()).ToList(); // random order //Grab a local instance of the new CampaignConfig, or upgrade us. CampaignConfig config = GetCampaignConfig(path); Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("\nFiring..."); Console.ResetColor(); int counter = 0; bool rateLimiterGood = true; foreach (string filename in existingFileNames) { if (!rateLimiterGood) { //Something is wrong and we've overshot our 60 tweets per hour limit. Bail so nobody get's banned Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("******* You've gone too big and are in danger of overshooting your rate limit.\nWait an hour and try again so you don't get banned. *******"); Console.ResetColor(); break; } StringBuilder sb = new StringBuilder(); if (addPings) { AddMentions(sb, config); } AddHashtags(sb, path, addDefaultHashtags); // reloads every time so we can inject new hashtags //DOIT bool twatted = TweetWithImage(sb.ToString(), filename); if (twatted) { // Add to the list of what we've already twatted and show the user postedFileNames.Add(filename); FileHelper.WriteJSONToFile(String.Format(@"{0}\hashtags\filenames.json", path), postedFileNames); string fn = Path.GetFileName(filename); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\n{0}", fn); Console.ResetColor(); //Update the TweetPerHour data rateLimiterGood = UpdateTweetsPerHour(); counter++; if (counter < existingFileNames.Count) { //get a random pause time between configured min and max, in millisec int min = (config.MinimumDelay * 60000); int max = config.MaximumDelay * 60000; int sleep = rnd.Next(min, max); Console.WriteLine(String.Format("{0}: Memecannon sleeping for [{1}] seconds", DateTime.Now, (sleep / 1000))); SysThread.Thread.Sleep(sleep); } } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("{0} no tweet", filename); Console.ResetColor(); } } }