Skip to content

Commit 01bcb66

Browse files
committed
1 parent d8c7703 commit 01bcb66

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.coder.toolbox.feed
2+
3+
import retrofit2.Response
4+
import retrofit2.http.GET
5+
import retrofit2.http.Url
6+
7+
/**
8+
* Retrofit API for fetching JetBrains IDE product feeds.
9+
*
10+
* Fetches product information from data.services.jetbrains.com for both
11+
* release and EAP (Early Access Program) builds.
12+
*/
13+
interface JetBrainsFeedApi {
14+
/**
15+
* Fetch the product feed from the specified URL.
16+
*
17+
* @param url The full URL to fetch (e.g., https://data.services.jetbrains.com/products?type=release)
18+
* @return Response containing a list of IDE products
19+
*/
20+
@GET
21+
suspend fun fetchFeed(@Url url: String): Response<List<IdeProduct>>
22+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.coder.toolbox.feed
2+
3+
import com.coder.toolbox.CoderToolboxContext
4+
import com.coder.toolbox.cli.ex.ResponseException
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.withContext
7+
import java.net.HttpURLConnection.HTTP_OK
8+
9+
/**
10+
* Service for fetching JetBrains IDE product feeds.
11+
*
12+
* This service fetches IDE product information from JetBrains data services,
13+
* parsing the response and extracting relevant IDE information.
14+
*/
15+
class JetBrainsFeedService(
16+
private val context: CoderToolboxContext,
17+
private val feedApi: JetBrainsFeedApi
18+
) {
19+
companion object {
20+
private const val RELEASE_FEED_URL = "https://data.services.jetbrains.com/products?type=release"
21+
private const val EAP_FEED_URL = "https://data.services.jetbrains.com/products?type=eap"
22+
}
23+
24+
/**
25+
* Fetch the release feed and return a list of IDEs.
26+
*
27+
* @return List of IDE objects from the release feed
28+
* @throws ResponseException if the request fails
29+
*/
30+
suspend fun fetchReleaseFeed(): List<Ide> {
31+
return fetchFeed(RELEASE_FEED_URL, "release")
32+
}
33+
34+
/**
35+
* Fetch the EAP (Early Access Program) feed and return a list of IDEs.
36+
*
37+
* @return List of IDE objects from the EAP feed
38+
* @throws ResponseException if the request fails
39+
*/
40+
suspend fun fetchEapFeed(): List<Ide> {
41+
return fetchFeed(EAP_FEED_URL, "eap")
42+
}
43+
44+
/**
45+
* Fetch a feed from the specified URL and parse it into a list of IDEs.
46+
*
47+
* @param url The URL to fetch from
48+
* @param feedType The type of feed (for logging and error messages)
49+
* @return List of IDE objects
50+
* @throws ResponseException if the request fails
51+
*/
52+
private suspend fun fetchFeed(url: String, feedType: String): List<Ide> = withContext(Dispatchers.IO) {
53+
context.logger.info("Fetching $feedType feed from $url")
54+
55+
val response = feedApi.fetchFeed(url)
56+
57+
when (response.code()) {
58+
HTTP_OK -> {
59+
val products = response.body() ?: emptyList()
60+
context.logger.info("Successfully fetched ${products.size} products from $feedType feed")
61+
62+
// Flatten all products and their releases into a list of Ide objects
63+
products.flatMap { product ->
64+
product.releases.map { release ->
65+
Ide.from(product, release)
66+
}
67+
}
68+
}
69+
70+
else -> {
71+
throw ResponseException(
72+
"Failed to fetch $feedType feed from $url",
73+
response.code()
74+
)
75+
}
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)