예제 #1
0
        public async Task Update(string userId, ArticlePrimaryKey key, UpdateArticleViewModel request)
        {
            var article = await _context.Article.FirstOrDefaultAsync(x =>
                                                                     x.CreatedYear == key.CreatedYear && x.TitleShrinked == key.TitleShrinked).CAF();

            string contentChecksumPreUpdate = ChecksumAlgorithm.ComputeMD5Checksum(article.Content);

            _mapper.Map(request, article);
            _articleFactory.SetUpdated(article);

            await EnsureRequestOfNarrationIfNarratable(article, contentChecksumPreUpdate).CAF();

            await using var transaction = await _context.Database.BeginTransactionAsync().CAF();

            try
            {
                await _context.SaveChangesAsync().CAF();

                await transaction.CommitAsync().CAF();
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                throw new FailedOperationException();
            }
        }
예제 #2
0
        public async Task <ArticlePrimaryKey> Add(string userId, AddArticleRequest request)
        {
            var    article       = _articleFactory.Create(request, userId);
            string titleShrinked = article.TitleShrinked;

            // Check that no other article has same titleShrinked, else generate a new titleShrinked
            var key = new ArticlePrimaryKey(article.CreatedYear, titleShrinked);

            while (await Exists(key).CAF())
            {
                titleShrinked         = RandomiseExistingShrinkedTitle(ref titleShrinked);
                key.TitleShrinked     = titleShrinked;
                article.TitleShrinked = titleShrinked;
            }

            await using var transaction = await _context.Database.BeginTransactionAsync().CAF();

            await _context.Article.AddAsync(article).CAF();

            try
            {
                await _context.SaveChangesAsync().CAF();

                await transaction.CommitAsync().CAF();
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                _logger.LogError(e.StackTrace);
                throw new FailedOperationException();
            }

            return(key);
        }
예제 #3
0
        public async Task Delete(ArticlePrimaryKey key)
        {
            var article = await _context.Article.FirstOrDefaultAsync(x =>
                                                                     x.CreatedYear == key.CreatedYear && x.TitleShrinked == key.TitleShrinked)
                          .ConfigureAwait(false);

            if (article is null)
            {
                return;
            }

            var associatedTagArticles = await _context.TagArticle.AsNoTracking().Where(x =>
                                                                                       x.ArticleCreatedYear == article.CreatedYear && x.ArticleTitleShrinked == article.TitleShrinked)
                                        .ToListAsync().ConfigureAwait(false);

            await using var transaction = await _context.Database.BeginTransactionAsync().ConfigureAwait(false);

            try
            {
                _context.TagArticle.RemoveRange(associatedTagArticles);
                _context.Article.Remove(article);
                await _context.SaveChangesAsync().ConfigureAwait(false);

                await transaction.CommitAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                throw new FailedOperationException();
            }
        }
예제 #4
0
        public async Task <bool> AuthorizedFor(ArticlePrimaryKey key, string userId)
        {
            var article = await(await _client.Article().FindAsync(x => x.Id == key.Id, new FindOptions <Article>()
            {
                Projection = Builders <Article> .Projection.Include(x => x.AuthorId)
            }).CAF()).FirstOrDefaultAsync().CAF();

            return(article.AuthorId == userId);
        }
예제 #5
0
        public async Task <ArticleViewModel> Get(ArticlePrimaryKey key, string viewerUserId = null)
        {
            var article = await _context.Article.AsNoTracking()
                          .Include(x => x.Series)
                          .FirstOrDefaultAsync(x => x.CreatedYear == key.CreatedYear && x.TitleShrinked == key.TitleShrinked)
                          .CAF();

            if (article is null)
            {
                return(null);
            }
            if ((!article.EverPublished || article.ForceFullyUnlisted || article.Draft) && article.AuthorId != viewerUserId)
            {
                return(null);
            }
            // if (article.Draft && article.AuthorId != viewerUserId) return null;

            // Get author full name
            var author = await _context.User.AsNoTracking()
                         .Select(x => new
            {
                x.Id,
                x.Name
            })
                         .FirstOrDefaultAsync(x => x.Id == article.AuthorId).ConfigureAwait(false);

            // Get tags associated with article
            var tags = await(from ta in _context.TagArticle
                             join t in _context.Tag.AsNoTracking() on ta.TagId equals t.Id
                             where
                             ta.ArticleCreatedYear == key.CreatedYear &&
                             ta.ArticleTitleShrinked == key.TitleShrinked
                             select t
                             ).ToListAsync().ConfigureAwait(false);

            ArticleSeriesArticles articleSeriesArticles = new ArticleSeriesArticles();

            if (article.Series is not null)
            {
                var lightArticleViews = await _context.Article.AsNoTracking()
                                        .Where(x => x.SeriesId == article.SeriesId)
                                        .OrderBy(x => x.CreatedAt)
                                        .Select(x => new LightArticleView
                {
                    Title         = x.Title,
                    TitleShrinked = x.TitleShrinked,
                    CreatedYear   = x.CreatedYear
                })
                                        .ToListAsync().ConfigureAwait(false);

                articleSeriesArticles.SeriesId    = article.Series.Id;
                articleSeriesArticles.SeriesTitle = article.Series.Title;
                articleSeriesArticles.Articles    = lightArticleViews;
            }

            return(new ArticleViewModel(article, tags, author.Name, articleSeriesArticles));
        }
예제 #6
0
        public async Task Update(string userId, ArticlePrimaryKey key, UpdateArticleViewModel request)
        {
            var article = await(await _client.Article().FindAsync(x => x.Id == key.Id).CAF())
                          .FirstOrDefaultAsync().CAF();
            string contentChecksumPreUpdate = ChecksumAlgorithm.ComputeMD5Checksum(article.Content);

            _mapper.Map(request, article);
            _articleFactory.SetUpdated(article);

            await EnsureRequestOfNarrationIfNarratable(article, contentChecksumPreUpdate).CAF();

            await _client.Article().FindOneAndReplaceAsync(x => x.Id == key.Id, article).CAF();
        }
예제 #7
0
        public async Task <bool> AuthorizedFor(ArticlePrimaryKey key, string userId)
        {
            string articleAuthorId = await _context.Article.AsNoTracking()
                                     .Where(x => x.CreatedYear == key.CreatedYear && x.TitleShrinked == key.TitleShrinked)
                                     .Select(x => x.AuthorId)
                                     .FirstOrDefaultAsync().CAF();

            if (string.IsNullOrEmpty(articleAuthorId))
            {
                throw new ArticleNotFoundException();
            }

            return(articleAuthorId == userId);
        }
예제 #8
0
        public async Task Share(ArticlePrimaryKey primaryKey)
        {
            var article = await _context.Article.FirstOrDefaultAsync(x =>
                                                                     x.CreatedYear == primaryKey.CreatedYear && x.TitleShrinked == primaryKey.TitleShrinked).CAF();

            if (article is null)
            {
                throw new ArticleNotFoundException();
            }

            article.Shares++;

            _context.Entry(article).Property(x => x.Shares).IsModified = true;
            await _context.SaveChangesAsync().CAF();
        }
예제 #9
0
        public async Task CompletedNarration(ArticlePrimaryKey key, string cdnUrl)
        {
            var article = await _context.Article.FirstOrDefaultAsync(x => x.CreatedYear == key.CreatedYear &&
                                                                     x.TitleShrinked == key.TitleShrinked)
                          .ConfigureAwait(false);

            if (article is null || !article.Narratable)
            {
                return;
            }

            article.NarrationMp3Url = cdnUrl;

            _context.Attach(article).Property(x => x.NarrationMp3Url).IsModified = true;
            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
예제 #10
0
        public async Task UpdateForcefullUnlist(ArticlePrimaryKey key, bool forcefullyUnlisted)
        {
            var article = await _context.Article
                          .FirstOrDefaultAsync(x => x.CreatedYear == key.CreatedYear &&
                                               x.TitleShrinked == key.TitleShrinked).CAF();

            if (article is null)
            {
                return;
            }

            article.ForceFullyUnlisted = forcefullyUnlisted;

            _context.Update(article);
            await _context.SaveChangesAsync().CAF();
        }
예제 #11
0
        public async Task <ArticleViewModel> Get(ArticlePrimaryKey primaryKey, string viewerUserId = null)
        {
            var article = await(await _client.Article().FindAsync(x => x.Id == primaryKey.Id).CAF())
                          .FirstOrDefaultAsync().CAF();

            if (article is null)
            {
                return(null);
            }
            if ((!article.EverPublished || article.ForceFullyUnlisted || article.Draft) && article.AuthorId != viewerUserId)
            {
                return(null);
            }

            var author = await(await _client.User().FindAsync(x => x.Id == article.AuthorId).CAF())
                         .FirstOrDefaultAsync().CAF();
            var tags = (await(await _client.Tag().FindAsync(x => article.TagsIds.Contains(x.Id)).CAF()).ToListAsync()
                        .CAF());

            // TODO enable article series to bring articles in same series

            return(new ArticleViewModel(article, tags, author.Name, new ArticleSeriesArticles()));
        }
예제 #12
0
 public Task CompletedNarration(ArticlePrimaryKey key, string cdnUrl)
 {
     throw new System.NotImplementedException();
 }
예제 #13
0
 public async Task UpdateForcefullUnlist(ArticlePrimaryKey key, bool forcefullyUnlisted)
 {
     await _client.Article().UpdateOneAsync(x => x.Id == key.Id,
                                            Builders <Article> .Update.Set(x => x.ForceFullyUnlisted, forcefullyUnlisted)).CAF();
 }
예제 #14
0
 public async Task Delete(ArticlePrimaryKey key)
 {
     await _client.Article().DeleteOneAsync(x => x.Id == key.Id).CAF();
 }
예제 #15
0
 public async Task Share(ArticlePrimaryKey primaryKey)
 {
     await _client.Article().FindOneAndUpdateAsync(x => x.Id == primaryKey.Id,
                                                   Builders <Article> .Update.Inc(x => x.Shares, 1)).CAF();
 }
예제 #16
0
 private async Task <bool> Exists(ArticlePrimaryKey key)
 {
     return(await _context.Article.AsNoTracking()
            .AnyAsync(x => x.CreatedYear == key.CreatedYear && x.TitleShrinked == key.TitleShrinked).CAF());
 }