@@ -25,152 +25,173 @@ public async static Task RunAsync(PerformContext context)
2525
2626 var _db = _redis . GetDatabase ( 5 ) ;
2727
28- Console . WriteLine ( "Fetching all games" ) ;
28+ using ( var jobLock = new RedisJobLock ( _redis , "GetLatestUpdatedModPerGame" ) )
29+ {
30+ if ( ! await jobLock . TryTakeLockAsync ( ) )
31+ {
32+ return ;
33+ }
34+
35+ Console . WriteLine ( "Fetching all games" ) ;
2936
30- var allGames = new List < Game > ( ) ;
37+ var allGames = new List < Game > ( ) ;
3138
32- DateTimeOffset lastUpdatedMod = DateTimeOffset . MinValue ;
33- Mod ? latestUpdatedModData = null ;
34- CurseForge . APIClient . Models . Files . File ? latestUpdatedFileData = null ;
39+ DateTimeOffset lastUpdatedMod = DateTimeOffset . MinValue ;
40+ Mod ? latestUpdatedModData = null ;
41+ CurseForge . APIClient . Models . Files . File ? latestUpdatedFileData = null ;
3542
36- var privateGames = await db . ExecuteListAsync < ProcessingGames > (
37- "SELECT * FROM ProcessingGames WHERE Disabled = 0 AND ModCount > 0"
38- ) ;
43+ var privateGames = await db . ExecuteListAsync < ProcessingGames > (
44+ "SELECT * FROM ProcessingGames WHERE Disabled = 0 AND ModCount > 0"
45+ ) ;
3946
40- foreach ( var privateGame in privateGames )
41- {
42- if ( ! allGames . Any ( g => g . Id == privateGame . GameId ) )
47+ foreach ( var privateGame in privateGames )
4348 {
44- var game = await cfClient . GetGameAsync ( privateGame . GameId ) ;
45- if ( game != null && game . Data != null )
49+ if ( ! allGames . Any ( g => g . Id == privateGame . GameId ) )
4650 {
47- allGames . Add ( game . Data ) ;
48- }
51+ var game = await cfClient . GetGameAsync ( privateGame . GameId ) ;
52+ if ( game != null && game . Data != null )
53+ {
54+ allGames . Add ( game . Data ) ;
55+ }
4956
50- if ( game != null && game . Error != null && game . Error . ErrorCode != 404 )
51- {
52- Console . WriteLine ( $ "Error fetching game info for { privateGame . Id } : { game . Error . ErrorMessage } ") ;
53- continue ;
57+ if ( game != null && game . Error != null && game . Error . ErrorCode != 404 )
58+ {
59+ Console . WriteLine (
60+ $ "Error fetching game info for { privateGame . Id } : { game . Error . ErrorMessage } ") ;
61+ continue ;
62+ }
63+
64+ await Task . Delay ( 100 ) ;
5465 }
55- await Task . Delay ( 100 ) ;
5666 }
57- }
58-
59- foreach ( var game in allGames )
60- {
61- Console . WriteLine ( $ "Starting to check for latest updated mod for { game . Name } (GameId: { game . Id } )") ;
62- await _db . StringSetAsync ( $ "cf-game-{ game . Id } ", JsonSerializer . Serialize ( game ) , TimeSpan . FromDays ( 1 ) ) ;
6367
64- await Task . Delay ( 100 ) ;
68+ foreach ( var game in allGames )
69+ {
70+ Console . WriteLine (
71+ $ "Starting to check for latest updated mod for { game . Name } (GameId: { game . Id } )") ;
72+ await _db . StringSetAsync ( $ "cf-game-{ game . Id } ", JsonSerializer . Serialize ( game ) ,
73+ TimeSpan . FromDays ( 1 ) ) ;
6574
66- var latestUpdatedMod = await cfClient . SearchModsAsync ( game . Id , sortField : ModsSearchSortField . LastUpdated , sortOrder : ModsSearchSortOrder . Descending , pageSize : 1 ) ;
75+ await Task . Delay ( 100 ) ;
6776
68- if ( latestUpdatedMod != null && latestUpdatedMod . Error != null )
69- {
70- Console . WriteLine ( $ "Error fetching latest updated mod for { game . Name } (GameId: { game . Id } ): { latestUpdatedMod . Error . ErrorMessage } ") ;
71- continue ;
72- }
77+ var latestUpdatedMod = await cfClient . SearchModsAsync ( game . Id ,
78+ sortField : ModsSearchSortField . LastUpdated , sortOrder : ModsSearchSortOrder . Descending ,
79+ pageSize : 1 ) ;
7380
74- if ( latestUpdatedMod != null && latestUpdatedMod . Pagination != null && latestUpdatedMod . Pagination . ResultCount > 0 )
75- {
76- await db . ExecuteNonQueryAsync ( "UPDATE ProcessingGames SET LastUpdate = GETUTCDATE(), ModCount = @modCount WHERE GameId = @gameId" ,
77- new SqlParameter ( "@modCount" , latestUpdatedMod . Pagination . TotalCount ) ,
78- new SqlParameter ( "@gameId" , game . Id )
79- ) ;
80-
81- var mod = latestUpdatedMod . Data . First ( ) ;
82- var latestUpdatedFile = mod . LatestFiles . OrderByDescending ( f => f . FileDate ) . FirstOrDefault ( ) ;
83- if ( latestUpdatedFile != null )
81+ if ( latestUpdatedMod != null && latestUpdatedMod . Error != null )
8482 {
85- Console . WriteLine ( $ "Latest updated mod for { game . Name } (GameId: { game . Id } ) is { mod . Name } (ModId: { mod . Id } ) with { mod . DownloadCount } downloads and the latest file was updated { latestUpdatedFile . FileDate } ") ;
86- if ( lastUpdatedMod < latestUpdatedFile . FileDate )
87- {
88- lastUpdatedMod = latestUpdatedFile . FileDate ;
89- latestUpdatedModData = mod ;
90- latestUpdatedFileData = latestUpdatedFile ;
91- }
92-
93- await _db . StringSetAsync ( $ "cf-mod-{ mod . Id } ", JsonSerializer . Serialize ( mod ) , TimeSpan . FromDays ( 1 ) ) ;
94- await _db . StringSetAsync ( $ "cf-file-{ latestUpdatedFile . Id } ", JsonSerializer . Serialize ( latestUpdatedFile ) , TimeSpan . FromDays ( 1 ) ) ;
83+ Console . WriteLine (
84+ $ "Error fetching latest updated mod for { game . Name } (GameId: { game . Id } ): { latestUpdatedMod . Error . ErrorMessage } ") ;
85+ continue ;
86+ }
9587
96- var existingGame = await db . ExecuteSingleRowAsync < FileProcessingStatus > (
97- "SELECT * FROM fileProcessingStatus WHERE gameId = @gameId" ,
88+ if ( latestUpdatedMod != null && latestUpdatedMod . Pagination != null &&
89+ latestUpdatedMod . Pagination . ResultCount > 0 )
90+ {
91+ await db . ExecuteNonQueryAsync (
92+ "UPDATE ProcessingGames SET LastUpdate = GETUTCDATE(), ModCount = @modCount WHERE GameId = @gameId" ,
93+ new SqlParameter ( "@modCount" , latestUpdatedMod . Pagination . TotalCount ) ,
9894 new SqlParameter ( "@gameId" , game . Id )
9995 ) ;
10096
101- if ( existingGame == null )
97+ var mod = latestUpdatedMod . Data . First ( ) ;
98+ var latestUpdatedFile = mod . LatestFiles . OrderByDescending ( f => f . FileDate ) . FirstOrDefault ( ) ;
99+ if ( latestUpdatedFile != null )
102100 {
103- // New game, insert it
104- await db . ExecuteNonQueryAsync (
105- "INSERT INTO fileProcessingStatus (last_updated_utc, gameId, modId, fileId) VALUES (@last_updated_utc, @gameId, @modId, @fileId)" ,
106- new SqlParameter ( "@last_updated_utc" , latestUpdatedFile . FileDate ) ,
107- new SqlParameter ( "@gameId" , game . Id ) ,
108- new SqlParameter ( "@modId" , mod . Id ) ,
109- new SqlParameter ( "@fileId" , latestUpdatedFile . Id )
101+ Console . WriteLine (
102+ $ "Latest updated mod for { game . Name } (GameId: { game . Id } ) is { mod . Name } (ModId: { mod . Id } ) with { mod . DownloadCount } downloads and the latest file was updated { latestUpdatedFile . FileDate } ") ;
103+ if ( lastUpdatedMod < latestUpdatedFile . FileDate )
104+ {
105+ lastUpdatedMod = latestUpdatedFile . FileDate ;
106+ latestUpdatedModData = mod ;
107+ latestUpdatedFileData = latestUpdatedFile ;
108+ }
109+
110+ await _db . StringSetAsync ( $ "cf-mod-{ mod . Id } ", JsonSerializer . Serialize ( mod ) ,
111+ TimeSpan . FromDays ( 1 ) ) ;
112+ await _db . StringSetAsync ( $ "cf-file-{ latestUpdatedFile . Id } ",
113+ JsonSerializer . Serialize ( latestUpdatedFile ) , TimeSpan . FromDays ( 1 ) ) ;
114+
115+ var existingGame = await db . ExecuteSingleRowAsync < FileProcessingStatus > (
116+ "SELECT * FROM fileProcessingStatus WHERE gameId = @gameId" ,
117+ new SqlParameter ( "@gameId" , game . Id )
110118 ) ;
119+
120+ if ( existingGame == null )
121+ {
122+ // New game, insert it
123+ await db . ExecuteNonQueryAsync (
124+ "INSERT INTO fileProcessingStatus (last_updated_utc, gameId, modId, fileId) VALUES (@last_updated_utc, @gameId, @modId, @fileId)" ,
125+ new SqlParameter ( "@last_updated_utc" , latestUpdatedFile . FileDate ) ,
126+ new SqlParameter ( "@gameId" , game . Id ) ,
127+ new SqlParameter ( "@modId" , mod . Id ) ,
128+ new SqlParameter ( "@fileId" , latestUpdatedFile . Id )
129+ ) ;
130+ }
131+ else
132+ {
133+ // Existing game, update it
134+ await db . ExecuteNonQueryAsync (
135+ "UPDATE fileProcessingStatus SET last_updated_utc = @last_updated_utc, modId = @modId, fileId = @fileId WHERE gameId = @gameId" ,
136+ new SqlParameter ( "@last_updated_utc" , latestUpdatedFile . FileDate ) ,
137+ new SqlParameter ( "@modId" , mod . Id ) ,
138+ new SqlParameter ( "@fileId" , latestUpdatedFile . Id ) ,
139+ new SqlParameter ( "@gameId" , game . Id )
140+ ) ;
141+ }
111142 }
112143 else
113144 {
114- // Existing game, update it
115- await db . ExecuteNonQueryAsync (
116- "UPDATE fileProcessingStatus SET last_updated_utc = @last_updated_utc, modId = @modId, fileId = @fileId WHERE gameId = @gameId" ,
117- new SqlParameter ( "@last_updated_utc" , latestUpdatedFile . FileDate ) ,
118- new SqlParameter ( "@modId" , mod . Id ) ,
119- new SqlParameter ( "@fileId" , latestUpdatedFile . Id ) ,
120- new SqlParameter ( "@gameId" , game . Id )
121- ) ;
145+ Console . WriteLine ( $ "No updated files found for { game . Name } and mod { mod . Name } ") ;
122146 }
123147 }
124148 else
125149 {
126- Console . WriteLine ( $ "No updated files found for { game . Name } and mod { mod . Name } ") ;
150+ Console . WriteLine ( $ "No mods found for { game . Name } ") ;
127151 }
128152 }
129- else
130- {
131- Console . WriteLine ( $ "No mods found for { game . Name } ") ;
132- }
133- }
134153
135- Console . WriteLine ( $ "Last updated mod was updated { lastUpdatedMod } ") ;
154+ Console . WriteLine ( $ "Last updated mod was updated { lastUpdatedMod } ") ;
136155
137- if ( lastUpdatedMod < DateTimeOffset . UtcNow . AddHours ( - 3 ) && latestUpdatedModData != null && latestUpdatedFileData != null )
138- {
139- Console . WriteLine ( "No mods were updated in the last 3 hours, file processing might be down." ) ;
156+ if ( lastUpdatedMod < DateTimeOffset . UtcNow . AddHours ( - 3 ) && latestUpdatedModData != null &&
157+ latestUpdatedFileData != null )
158+ {
159+ Console . WriteLine ( "No mods were updated in the last 3 hours, file processing might be down." ) ;
140160
141- var warned = await _db . StringGetAsync ( "cf-file-processing-warning" ) ;
161+ var warned = await _db . StringGetAsync ( "cf-file-processing-warning" ) ;
142162
143- if ( warned . HasValue && warned == "true" )
144- {
145- Console . WriteLine ( "Already warned about this, skipping." ) ;
146- return ;
147- }
163+ if ( warned . HasValue && warned == "true" )
164+ {
165+ Console . WriteLine ( "Already warned about this, skipping." ) ;
166+ return ;
167+ }
148168
149- var httpClient = scope . ServiceProvider . GetRequiredService < IHttpClientFactory > ( ) . CreateClient ( ) ;
150- var discordWebhook = Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . Machine ) ??
151- Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . User ) ??
152- Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . Process ) ??
153- string . Empty ;
169+ var httpClient = scope . ServiceProvider . GetRequiredService < IHttpClientFactory > ( ) . CreateClient ( ) ;
170+ var discordWebhook =
171+ Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . Machine ) ??
172+ Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . User ) ??
173+ Environment . GetEnvironmentVariable ( "DISCORD_WEBHOOK" , EnvironmentVariableTarget . Process ) ??
174+ string . Empty ;
154175
155- if ( ! string . IsNullOrWhiteSpace ( discordWebhook ) )
156- {
157- var message = @$ "No mods were updated in the last 3 hours, file processing might be down.
176+ if ( ! string . IsNullOrWhiteSpace ( discordWebhook ) )
177+ {
178+ var message = @$ "No mods were updated in the last 3 hours, file processing might be down.
158179Last updated mod was updated { lastUpdatedMod } , and it was { latestUpdatedModData . Name }
159180(ProjectID: { latestUpdatedModData . Id } , FileId: { latestUpdatedFileData . Id } )
160181https://cflookup.com/{ latestUpdatedModData . Id } " ;
161- var payload = new
162- {
163- content = message ,
164- flags = 4
165- } ;
182+ var payload = new
183+ {
184+ content = message ,
185+ flags = 4
186+ } ;
166187
167- var json = JsonSerializer . Serialize ( payload ) ;
168- var content = new StringContent ( json , Encoding . UTF8 , "application/json" ) ;
169- await httpClient . PostAsync ( discordWebhook , content ) ;
170- }
188+ var json = JsonSerializer . Serialize ( payload ) ;
189+ var content = new StringContent ( json , Encoding . UTF8 , "application/json" ) ;
190+ await httpClient . PostAsync ( discordWebhook , content ) ;
191+ }
171192
172- await _db . StringSetAsync ( "cf-file-processing-warning" , "true" , TimeSpan . FromHours ( 1 ) ) ;
173- return ;
193+ await _db . StringSetAsync ( "cf-file-processing-warning" , "true" , TimeSpan . FromHours ( 1 ) ) ;
194+ }
174195 }
175196 }
176197 }
0 commit comments