Automated Task

创建标签

Type Scheduled

Date Executed 7/18/2024, 8:00:00 AM

Created 7/17/2024, 3:40:37 PM

Updated 7/17/2024, 3:40:37 PM

Description 创建投稿时可选标签。

Code
1
using Microsoft.Extensions.Logging;
2
using Microsoft.Extensions.DependencyInjection;
3
using PhiZoneApi.Models;
4
using PhiZoneApi.Interfaces;
5
using System.Collections.Generic;
6
using System.Threading.Tasks;
7
using System.Linq;
8
using System;
9
using PhiZoneApi.Enums;
10

11
Dictionary<string, string> tags = new()
12
{
13
    { "7PJ-0-2", "撞色:多人合作谱面。" },
14
    { "7PJ-0-3", "这是我最好的作品。" },
15
    { "7PJ-0-4", "我将获得前 20% 的评委分排名!" },
16
    { "7PJ-1-1", "主题-色彩:选择以色彩为主题的曲目。" },
17
    { "7PJ-1-2", "主题-极限:选择以极限为主题的曲目。" },
18
    { "7PJ-1-3", "主题-反驳:选择以反驳为主题的曲目。" },
19
    { "7PJ-1-4", "选择 2014 年或更早发行的曲目。" },
20
    { "7PJ-1-5", "选择 2024 年发行的曲目。" },
21
    { "7PJ-1-6", "选择自己创作的曲目。" },
22
    { "7PJ-1-7", "第二次机会:选择自己曾经制谱的曲目(必须公开发布过;不必须为 Phigros 自制)。" },
23
    { "7PJ-1-8", "你喜欢就好!选择自己喜欢的曲目。" },
24
    { "7PJ-2-1", "使用至多 8 根判定线。" },
25
    { "7PJ-2-1-ex", "使用至多 4 根判定线。" },
26
    { "7PJ-2-2", "制作一张单手游玩的谱面。" },
27
    { "7PJ-2-3", "画面中至多同时出现 8 个音符。" },
28
    { "7PJ-2-3-ex", "画面中至多同时出现 4 个音符。" },
29
    { "7PJ-2-4", "同一种 Note 至多连续判定 3 次。" },
30
    { "7PJ-2-5", "创作同一曲目的不同差分。" },
31
    { "7PJ-2-6", "创作一张完全对称的谱面。" },
32
    { "7PJ-2-7", "谱面中判定线要么完全透明,要么完全不透明。" },
33
    { "7PJ-2-7-ex", "谱面中不出现可见的判定线。" },
34
    { "7PJ-2-8", "谱面中 Flick 的数量大于曲目的秒数。" },
35
    { "7PJ-3-1", "第十戒律:选择一首曲目,制作至少两张谱面。玩家可以在不同设备上各运行一张谱面,并同时游玩。" },
36
    { "7PJ-3-2", "漫长的告别:谱面中至少出现两个这样的 Hold——从开始判定到结束判定,至少经过 8 秒,且期间有至少 20 个其他需要打击的 Tap 或 Hold 被完整判定。" },
37
    { "7PJ-3-2-ex", "漫长的告别 EX:从谱面的第一个音符开始,到最后音符结束,始终有至少一个 Hold处于判定中。" },
38
    { "7PJ-3-3", "神隐迷案:谱面中存在至少一个这样的段落——时长不小于 15 秒;画面中不能出现音符;判定不少于 20 个 Tap 或 Hold。" },
39
    { "7PJ-3-3-ex", "神隐迷案 EX:谱面中存在至少 100 个这样的 Tap 或 Hold——需要打击;在判定的前后各 1s 内,画面中不出现任何音符。" }
40
};
41
var target = (EventDivision)Target;
42
await using (var scope = ServiceProvider.CreateAsyncScope())
43
{
44
    var resourceService = scope.ServiceProvider.GetRequiredService<IResourceService>();
45
    var tagRepository = scope.ServiceProvider.GetRequiredService<ITagRepository>();
46
    var eventResourceRepository = scope.ServiceProvider.GetRequiredService<IEventResourceRepository>();
47

48
    var existingTags = await tagRepository.GetTagsAsync(predicate: e =>
49
        tags.Select(tag => resourceService.Normalize(tag.Key)).Contains(e.NormalizedName));
50
    Logger.LogInformation("Existing tags:");
51
    foreach (var tag in existingTags)
52
    {
53
        Logger.LogInformation("{Name} - {Description}", tag.Name, tag.Description);
54
    }
55

56
    var newTags = tags.Where(tag => existingTags.All(e => e.NormalizedName != resourceService.Normalize(tag.Key)))
57
        .Select((tag, i) => new Tag
58
        {
59
            Name = tag.Key,
60
            NormalizedName = resourceService.Normalize(tag.Key),
61
            Description = tag.Value,
62
            DateCreated = DateTimeOffset.UtcNow.Add(TimeSpan.FromMilliseconds(i))
63
        })
64
        .ToList();
65
    Logger.LogInformation("New tags:");
66
    foreach (var tag in newTags)
67
    {
68
        Logger.LogInformation("{Name} - {Description}", tag.Name, tag.Description);
69
    }
70

71
    await tagRepository.CreateTagsAsync(newTags);
72
    var resources = newTags.Union(existingTags)
73
        .Select((tag, i) => new EventResource
74
        {
75
            DivisionId = target.Id,
76
            ResourceId = tag.Id,
77
            TagId = tag.Id,
78
            Type = EventResourceType.Tag,
79
            DateCreated = DateTimeOffset.UtcNow.Add(TimeSpan.FromMilliseconds(i))
80
        });
81
    foreach (var resource in resources)
82
    {
83
        if (await eventResourceRepository.EventResourceExistsAsync(resource.DivisionId, resource.ResourceId)) continue;
84
        await eventResourceRepository.CreateEventResourceAsync(resource);
85
    }
86
}