public IMongoCollection <AnimatedImage> CreateAnimatedTestDB(string collectionName) { string connString = "mongodb://localhost:27017/?readPreference=primary&appname=kawaiitwitter&ssl=false"; string dbName = "unit-test-kawaii"; var db = new Database(connString, false, dbName); AnimatedImageCollection collection = new AnimatedImageCollection(db, collectionName, true); var animatedCollection = collection.AnimatedImages; //коллекцию очистить от данных var delFilter = Builders <AnimatedImage> .Filter.Exists(x => x.BlobName); animatedCollection.DeleteMany(delFilter); var sampleImages = SamplePostsDatabase.Images; //Загружаем в базу тест данные foreach (var img in sampleImages) { var findResult = animatedCollection.FindAsync(x => x.BlobName == img.BlobName).Result; var foundRecord = findResult.FirstOrDefault(); if (foundRecord != null) { continue; } animatedCollection.InsertOneAsync(img).Wait(); } return(animatedCollection); }
IMongoCollection <AnimatedImage> _PrepareAnimatedCollection(bool doEmptyCollection, bool doAllWithTweetDate) { string connString = "mongodb://localhost:27017/?readPreference=primary&appname=kawaiitwitter&ssl=false"; string dbName = "unit-test-kawaii"; string collName = "not-twitted-animated"; var db = new Database(connString, false, dbName); var animatedCollection = new AnimatedImageCollection(db, collName, true); var pages = animatedCollection.AnimatedImages; //удаляем все записи, заполняем тест данными var delFilter = Builders <AnimatedImage> .Filter.Exists(x => x.BlobName); pages.DeleteMany(delFilter); if (doEmptyCollection) { return(pages); //на этом все - пустая коллекция } AnimatedImage[] imgsToAdd = new AnimatedImage[] { _Img1, _Img2, _Img3, _Img4, _Img5 }; if (doAllWithTweetDate) { //здесь чуть сложнее - клонируем исходные данные, чтобы потенциально не мешать другим, и прошьем дату всем (порядок и разм.массива достаточна для тех, у кого нет своей даты твита) DateTime[] tweedDates = new DateTime[] { _TweetDate1, _TweetDate2, _TweetDate3 }; AnimatedImage[] imgsToAddCloned = new AnimatedImage[imgsToAdd.Length]; for (int i = 0; i < imgsToAdd.Length; i++) { var srcImg = imgsToAdd[i]; var img = new AnimatedImage { BlobName = srcImg.BlobName, TweetDate = srcImg.TweetDate }; if (img.TweetDate == null) { img.TweetDate = tweedDates[i]; } imgsToAddCloned[i] = img; } //for i imgsToAdd = imgsToAddCloned; } pages.InsertMany(imgsToAdd); return(pages); }
/// <summary> /// Вичитує блоби, аналізує чи є вони у базі, якщо ні - додає /// </summary> public async Task UpdateAnimatedBlobDataBase() { _Log.Log("UpdateAnimatedBlobDataBase started..."); var animatedImagesBlobContainer = new AnimatedImagesBlobContainer(_AzureBlobConnectionString); string[] blobNames = animatedImagesBlobContainer.GetBlobNames(); if (blobNames == null || blobNames.Length == 0) { _Log.Log("Blobs not found"); return; } _Log.Log("Found {0} animated blobs", blobNames.Length); var db = new Database(_AzureSiteDBConnectionString, true, null); AnimatedImageCollection animatedImageCollection = new AnimatedImageCollection(db, null, true); var imagesCollection = animatedImageCollection.AnimatedImages; int added = 0; foreach (var blobName in blobNames) { FilterDefinitionBuilder <AnimatedImage> def = new FilterDefinitionBuilder <AnimatedImage>(); var filter = def.Eq(x => x.BlobName, blobName); bool recordFound = false; using (var cursor = await imagesCollection.FindAsync(filter)) { while (cursor.MoveNext()) { foreach (var img in cursor.Current) { //что-то нашлось, пропуск... recordFound = true; break; } } } if (!recordFound) { //создаем новую запись в базе AnimatedImage animatedImage = new AnimatedImage { BlobName = blobName }; await imagesCollection.InsertOneAsync(animatedImage); added++; _Log.Log("Added: {0}", blobName); } } _Log.Log("UpdateAnimatedBlobDataBase finished, added: {0}", added); }
public void FindAnimatedByPage_Normal_Find() { string connString = "mongodb://localhost:27017/?readPreference=primary&appname=kawaiitwitter&ssl=false"; string dbName = "unit-test-kawaii"; string collName = "animatedimage-find-animated-by-page"; var db = new Database(connString, false, dbName); var animatedImageCollection = new AnimatedImageCollection(db, collName, true); var animated = animatedImageCollection.AnimatedImages; //коллекцию очистить от данных var delFilter = Builders <AnimatedImage> .Filter.Exists(x => x.BlobName); animated.DeleteMany(delFilter); AnimatedImage img1 = new AnimatedImage { BlobName = "codegeass:x1.gif", TweetDate = new DateTime(2020, 01, 01) }; AnimatedImage img2 = new AnimatedImage { BlobName = "codegeass:x2.gif", TweetDate = new DateTime(2020, 01, 02) }; AnimatedImage img3 = new AnimatedImage { BlobName = "shuumatsu-no-izetta:izetta1.gif", TweetDate = new DateTime(2020, 04, 26) }; AnimatedImage img4 = new AnimatedImage { BlobName = "shuumatsu-no-izetta:izetta2.gif", TweetDate = new DateTime(2020, 04, 27) }; AnimatedImage img5 = new AnimatedImage { BlobName = "deathnote:light1.gif", TweetDate = new DateTime(2020, 02, 10) }; AnimatedImage[] testImages = new AnimatedImage[] { img1, img2, img3, img4, img5 }; animated.InsertMany(testImages); //Теперь отбираем изображения для поста string url = "https://kawaii-mobile.com/2017/01/shuumatsu-no-izetta/"; var find = new FindAnimatedByPage(animated.AsQueryable(), new FolderFromURL(), new Formatter()); var result = find.GetAnimatedImagesForPage(url).Result; Assert.IsNotNull(result); Assert.IsTrue(result.Length == 2, "Должно быть найдено 2 записи"); var r3 = result.SingleOrDefault(x => x.BlobName == img3.BlobName); Assert.IsNotNull(r3, "Тест запись img3 не найдена"); Assert.IsTrue(r3.TweetDate == img3.TweetDate, "Тест запись r3.TweetDate==img3.TweetDate"); var r4 = result.SingleOrDefault(x => x.BlobName == img4.BlobName); Assert.IsNotNull(r4, "Тест запись img4 не найдена"); Assert.IsTrue(r4.TweetDate == img4.TweetDate, "Тест запись r4.TweetDate==img4.TweetDate"); //и еще не большой тест на не-существующую запись - поиск который ничего не найдет: string urlNotExistsAnimated = "https://kawaii-mobile.com/2019/11/maou-sama-retry/"; var result2 = find.GetAnimatedImagesForPage(urlNotExistsAnimated).Result; Assert.IsTrue(result2.Length == 0, "Ожидалось что result2 будет пустым массивом"); }
public static async Task Run([TimerTrigger("0 0 * * * *")] TimerInfo timer, ILogger log) { //https://docs.microsoft.com/ru-ru/azure/azure-functions/functions-bindings-timer?tabs=csharp#ncrontab-expressions //0 */5 * * * * - каждые 5 мин //"0 0 * * * *" - каждый час Logger logger = new Logger(log); logger.Log($"TweetPostFunction executed at: {DateTime.Now}"); string animatedBlobConnectionString = kawaii.twitter.core.Env.EnvironmentSecureData.GetValueFromEnvironment("env:kawaii_twitter_azure_animatedblob"); string azureSiteDBConnectionString = kawaii.twitter.core.Env.EnvironmentSecureData.GetValueFromEnvironment("env:kawaii_twitter_azure_sitepages"); if (string.IsNullOrEmpty(animatedBlobConnectionString)) { logger.LogError("animatedBlobConnectionString not found!"); return; } if (string.IsNullOrEmpty(azureSiteDBConnectionString)) { logger.LogError("azureSiteDBConnectionString not found!"); return; } IDatabase database = new Database(azureSiteDBConnectionString, true, null); logger.Log($"database connected: {DateTime.Now}"); //если в переменных задано что "не обновлять индексы", то мы сэкономим время работы в прод-окружении - индексы создаются один раз, //и дальше и так работают, хотя MongoDB и говорит что "нет проблем". //Если будет нужно обновлять индексы, или будет новое окружение (новая база, коллекция и прочее) то эту переменную среды надо убрать. //А когда все настроено и уже работает, ее можно создать для общего ускорения string dontCreateIndexesStr = kawaii.twitter.core.Env.EnvironmentSecureData.GetValueFromEnvironment("env:kawaii_twitter_dont_create_indexes"); bool dontCreateIndexes = false; if (!string.IsNullOrEmpty(dontCreateIndexesStr)) { bool.TryParse(dontCreateIndexesStr, out dontCreateIndexes); } if (dontCreateIndexes) { logger.Log("Indexes will not updated (found env:kawaii_twitter_dont_create_indexes)"); } AnimatedImageCollection animatedImageCollection = new AnimatedImageCollection(database, null, !dontCreateIndexes); var imagesCollection = animatedImageCollection.AnimatedImages; logger.Log($"imagesCollection init done: {DateTime.Now}"); SitePageCollection sitePageCollection = new SitePageCollection(database, null, !dontCreateIndexes); var sitePagesCollection = sitePageCollection.SitePages; logger.Log($"sitePagesCollection init done: {DateTime.Now}"); ITwitterTextCreator textCreator = new kawaii.twitter.core.Text.TwitterTextCreator(); IImageOnWeb imageOnWeb = new kawaii.twitter.core.HtmlParsers.ImageOnWeb(_HttpClient); ITwitterImageURL twitterImageURL = new kawaii.twitter.core.HtmlParsers.TwitterImageURL(_HttpClient); //--- блок для lastTweetUpdater var dateSupply = new kawaii.twitter.core.Env.DateSupply(); IAnimatedTweetDateUpdater animatedTweetDateUpdater = new AnimatedTweetDateUpdater(imagesCollection); ISitePageTweetDateUpdater sitePageTweetDateUpdater = new SitePageTweetDateUpdater(sitePagesCollection); ILastTweetUpdater lastTweetUpdater = new kawaii.twitter.core.SelectLogic.LastTweetUpdater(dateSupply, animatedTweetDateUpdater, sitePageTweetDateUpdater); //--- //сервису твиттера нужно передать авториз.данные var service = new kawaii.twitter.core.TwitterService.Service(); var animatedImagesBlobContainer = new AnimatedImagesBlobContainer(animatedBlobConnectionString); IBlobDownload blobDownload = animatedImagesBlobContainer; var randomSelector = new kawaii.twitter.core.SelectLogic.Randomize.RandomSelector(); int topQueryCount = 10; ISpecialDaySelector specialDaySelector = new SpecialDaySelector(dateSupply, randomSelector); string specialDayName = specialDaySelector.DetectSpecialDayName(); IFolderFromURL folderFromURL = new kawaii.twitter.core.SelectLogic.URL.FolderFromURL(); var formatter = new kawaii.twitter.core.SelectLogic.BlobName.Formatter(); IPageSelector pageSelectorForNewPages = new kawaii.twitter.core.SelectLogic.Page.NotTwittedPages(sitePagesCollection, randomSelector, specialDayName, topQueryCount); IFindAnimatedByPage findNewAnimatedByPage = new kawaii.twitter.core.SelectLogic.Images.Newly.NotTwittedAnimated(imagesCollection, randomSelector, topQueryCount, folderFromURL, formatter); IPageSelector pageSelectorForAnyPages = new kawaii.twitter.core.SelectLogic.Page.PageSelector(sitePagesCollection, randomSelector, specialDayName, topQueryCount); IFindAnimatedByPage findAnimatedByPage = new kawaii.twitter.core.SelectLogic.Images.Find.FindAnimatedByPage(imagesCollection.AsQueryable(), folderFromURL, formatter); IPageOrExternalImageSelector pageOrExternalImageSelector = new kawaii.twitter.core.SelectLogic.PageOrExternalImage.PageOrExternalImageSelector(); IAnimatedSelectorWithExcludeLast animatedSelectorWithExcludeLast = new kawaii.twitter.core.SelectLogic.Images.ExcludeUsed.AnimatedSelectorWithExcludeLast(); IPageForTwittingSelector pageForTwittingSelector = new kawaii.twitter.core.SelectLogic.PageForTwittingSelector(pageSelectorForNewPages, findNewAnimatedByPage, pageSelectorForAnyPages, findAnimatedByPage, pageOrExternalImageSelector, animatedSelectorWithExcludeLast, logger); var tweetCreator = new kawaii.twitter.core.TweetCreator(pageForTwittingSelector, textCreator, twitterImageURL, imageOnWeb, blobDownload, service, lastTweetUpdater, logger); logger.Log($"tweetCreator.Execute: {DateTime.Now}"); //выполнить твит заданной страницы и изображения await tweetCreator.Execute(); }