public async Task <List <BkTag> > GetHotAsync()
    {
        var sw = Stopwatch.StartNew();
        var re = await GetHotAsyncCore();

        _logger.LogInformation("Get Hot Tags cost {Time} ms", sw.ElapsedMilliseconds);
        return(re);

        async Task <List <BkTag> > GetHotAsyncCore()
        {
            var options = await _userOptionsService.GetOptionsAsync();

            var all = await _tagsRepo.GetAllAsync();

            var result = all
                         .Where(x => x.RelatedBkCount > 0)
                         .OrderByDescending(x => x.ClickedCount)
                         .ThenByDescending(x => x.LastClickTime)
                         .ThenByDescending(x => x.RelatedBkCount)
                         .Take(options.HotTagsFeature?.ListCount ?? 10)
                         .ToList();

            return(result);
        }
    }
    public async Task AddAsync(MsgItem item)
    {
        var records = await _notificationRepo.GetAllAsync();

        var groupName = item.Type.ToString();
        var record    = records.FirstOrDefault(x => x.Group == groupName);
        var now       = _clock.UtcNow;

        item.CreatedTime = now;
        if (record == null)
        {
            record = new NotificationRecord
            {
                Group = groupName,
                Id    = now,
                Items = new List <MsgItem>
                {
                    item
                },
                UpdateTime = now
            };
        }
        else
        {
            record.Items.Insert(0, item);
            while (record.Items.Count > 10)
            {
                record.Items.RemoveAt(record.Items.Count - 1);
            }
            record.UpdateTime = now;
        }

        await _notificationRepo.UpsertAsync(record);

        var status = await _simpleDataStorage.GetOrDefaultAsync <NotificationCenterStatus>();

        status.NewMessage = true;
        await _simpleDataStorage.SaveAsync(status);

        await _afEventHub.PublishAsync(new NewNotificationEvent());
    }
示例#3
0
    public async ValueTask StartAsync()
    {
        var list = await _bkRepo.GetAllAsync();

        foreach (var bk in list)
        {
            if (string.IsNullOrEmpty(bk.UrlHash))
            {
                bk.UrlHash = _urlHashService.GetHash(bk.Url);
                await _bkRepo.UpsertAsync(bk);
            }
        }
    }
示例#4
0
    public async Task AppendBookmarksAsync(IEnumerable <BookmarkNode> nodes)
    {
        var updated = false;
        var bkDic   = nodes.ToLookup(x => x.Url, x => new Bk
        {
            Title = x.Title,
            TitleLastUpdateTime = _clock.UtcNow,
            Url            = x.Url,
            UrlHash        = _urlHashService.GetHash(x.Url),
            LastCreateTime = x.DateAdded.HasValue
                ? DateTimeOffset.FromUnixTimeMilliseconds((long)x.DateAdded.Value).ToUnixTimeSeconds()
                : 0L,
            Tags   = x.Tags.Distinct().ToList(),
            Offset = GetOffset(x.Deepth, x.ParentNodeOffset, x.Offset),
        });
        var bookmarksKeys = bkDic.Select(x => x.Key).ToHashSet();

        _logger.LogDebug("Found {Count} bookmark", bookmarksKeys.Count);

        foreach (var grouping in bkDic)
        {
            var url  = grouping.Key;
            var node = grouping.First();
            var bk   = await _bkRepo.GetAsync(url);

            if (bk != null)
            {
                if (bk.Title != node.Title)
                {
                    bk.Title = node.Title;
                    bk.TitleLastUpdateTime = _clock.UtcNow;
                    await _bkRepo.UpsertAsync(bk);

                    updated = true;
                }
            }
        }

        var bks = await _bkRepo.GetAllAsync();

        var newKeys = bookmarksKeys.Except(bks.Select(x => x.Url)).ToArray();

        if (newKeys.Length > 0)
        {
            foreach (var key in newKeys)
            {
                var bk = bkDic[key].First();
                _logger.LogInformation($"Current Upsert Node :{bk.Title}");
                await _bkRepo.UpsertAsync(bk);

                if (bk.Tags?.Any() == true)
                {
                    foreach (var tag in bk.Tags)
                    {
                        await AppendTagsAsync(tag);
                    }
                }

                updated = true;
            }

            _logger.LogInformation("There are {Count} links new, add to storage", newKeys.Length);
        }

        if (updated)
        {
            await UpdateMetadataAsync();
        }
    }
示例#5
0
    private async Task <IEnumerable <SearchResultItem> > SearchCore(string searchText)
    {
        var source = await _bkRepo.GetAllAsync();

        var tags = await _tagRepo.GetAllAsync();

        if (string.IsNullOrWhiteSpace(searchText))
        {
            var latest = source
                         .Where(x => x.LastClickTime > 0 && x.ClickedCount > 0)
                         .OrderByDescending(x => x.LastClickTime)
                         .ThenByDescending(x => x.ClickedCount)
                         .Select(x => x.Id)
                         .Take(LatestCount)
                         .ToList();
            return(source
                   .Select(x =>
            {
                var r = new SearchResultItem(x)
                {
                    LastClickTime = x.LastClickTime
                };
                r.AddScore(ScoreReason.Const, 10);
                if (latest.FirstOrDefault(a => a == r.Bk.Id) != null)
                {
                    r.AddScore(ScoreReason.Latest, 10 - latest.FindIndex(a => a == r.Bk.Id));
                }
                return r;
            }));
        }

        var input = SearchInput.Parse(searchText);

        _logger.LogInformation(
            "Search text parse result, SourceText: {SearchInput} Keywords: {Keywords}, Tags: {Tags}",
            input.SourceText,
            input.Keywords,
            input.Tags);

        var tagDict   = tags.ToDictionary(x => x.Tag);
        var matchTags = tagDict
                        .Where(tag =>
                               input.Tags.Contains(tag.Key) ||
                               input.Keywords.Any(keyword => StringContains(tag.Key, keyword)))
                        .Select(x => x.Key)
                        .ToHashSet();

        var matchTagAlias = tagDict
                            .Where(tag => input.Keywords.Any(keyword =>
                                                             tag.Value.TagAlias.Values.Any(tagAlias => StringContains(tagAlias.Alias, keyword))))
                            .Select(x => x.Key)
                            .ToHashSet();

        var re = source
                 .Select(MatchBk)
                 .Where(x => x.Matched);

        return(re);

        SearchResultItem MatchBk(Bk item)
        {
            var result = new SearchResultItem(item)
            {
                ClickCount    = item.ClickedCount,
                LastClickTime = item.LastClickTime
            };

            result.AddScore(ScoreReason.Title, input.Keywords.Any(x => StringContains(item.Title, x)));

            result.AddScore(ScoreReason.TitleAlias, item.TitleAlias?.Values != null &&
                            item.TitleAlias.Values.Any(al =>
                                                       input.Keywords.Any(x =>
                                                                          StringContains(al.Alias, x))));

            result.AddScore(ScoreReason.Url, input.Keywords.Any(x => StringContains(item.Url, x)));
            if (item.Tags?.Any() == true)
            {
                result.AddScore(ScoreReason.Tags, item.Tags.Any(matchTags.Contains));
                result.AddScore(ScoreReason.TagAlias, item.Tags.Any(matchTagAlias.Contains));
            }

            if (result.Score > 0)
            {
                result.AddScore(ScoreReason.ClickCount, item.ClickedCount);
            }

            return(result);
        }