|
1 | | -using Flow.Launcher.Infrastructure.Http; |
2 | | -using Flow.Launcher.Infrastructure.Logger; |
| 1 | +using Flow.Launcher.Infrastructure.Logger; |
3 | 2 | using System; |
4 | 3 | using System.Collections.Generic; |
5 | | -using System.Net; |
6 | | -using System.Net.Http; |
7 | | -using System.Text.Json; |
8 | 4 | using System.Threading; |
9 | 5 | using System.Threading.Tasks; |
10 | 6 |
|
11 | 7 | namespace Flow.Launcher.Core.ExternalPlugins |
12 | 8 | { |
13 | 9 | public static class PluginsManifest |
14 | 10 | { |
15 | | - private const string manifestFileUrl = "https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json"; |
| 11 | + private static readonly CommunityPluginStore mainPluginStore = |
| 12 | + new("https://raw.githubusercontent.com/Flow-Launcher/Flow.Launcher.PluginsManifest/plugin_api_v2/plugins.json", |
| 13 | + "https://fastly.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json", |
| 14 | + "https://gcore.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json", |
| 15 | + "https://cdn.jsdelivr.net/gh/Flow-Launcher/Flow.Launcher.PluginsManifest@plugin_api_v2/plugins.json"); |
16 | 16 |
|
17 | 17 | private static readonly SemaphoreSlim manifestUpdateLock = new(1); |
18 | 18 |
|
19 | | - private static string latestEtag = ""; |
| 19 | + private static DateTime lastFetchedAt = DateTime.MinValue; |
| 20 | + private static TimeSpan fetchTimeout = TimeSpan.FromMinutes(2); |
20 | 21 |
|
21 | | - public static List<UserPlugin> UserPlugins { get; private set; } = new List<UserPlugin>(); |
| 22 | + public static List<UserPlugin> UserPlugins { get; private set; } |
22 | 23 |
|
23 | | - public static async Task UpdateManifestAsync(CancellationToken token = default) |
| 24 | + public static async Task UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false) |
24 | 25 | { |
25 | 26 | try |
26 | 27 | { |
27 | 28 | await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false); |
28 | 29 |
|
29 | | - var request = new HttpRequestMessage(HttpMethod.Get, manifestFileUrl); |
30 | | - request.Headers.Add("If-None-Match", latestEtag); |
31 | | - |
32 | | - using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false); |
33 | | - |
34 | | - if (response.StatusCode == HttpStatusCode.OK) |
| 30 | + if (UserPlugins == null || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout) |
35 | 31 | { |
36 | | - Log.Info($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Fetched plugins from manifest repo"); |
37 | | - |
38 | | - await using var json = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false); |
| 32 | + var results = await mainPluginStore.FetchAsync(token, usePrimaryUrlOnly).ConfigureAwait(false); |
39 | 33 |
|
40 | | - UserPlugins = await JsonSerializer.DeserializeAsync<List<UserPlugin>>(json, cancellationToken: token).ConfigureAwait(false); |
41 | | - |
42 | | - latestEtag = response.Headers.ETag.Tag; |
43 | | - } |
44 | | - else if (response.StatusCode != HttpStatusCode.NotModified) |
45 | | - { |
46 | | - Log.Warn($"|PluginsManifest.{nameof(UpdateManifestAsync)}|Http response for manifest file was {response.StatusCode}"); |
| 34 | + UserPlugins = results; |
| 35 | + lastFetchedAt = DateTime.Now; |
47 | 36 | } |
48 | 37 | } |
49 | 38 | catch (Exception e) |
|
0 commit comments