Skip to content

Commit 9384ee3

Browse files
committed
fix: endcursor for users who have more than 100 starred repos
1 parent 583010e commit 9384ee3

File tree

6 files changed

+68
-37
lines changed

6 files changed

+68
-37
lines changed

src/AwesomeGithubPortfolio.Core/Interfaces/IGithubService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ namespace AwesomeGithubPortfolio.Core.Interfaces
66
public interface IGithubService
77
{
88
Task<GitHubUser> FetchUserData(string username);
9-
Task<bool> UserHasStarred(string username);
9+
Task<bool> UserHasStarred(string username, string pageCursor = null);
1010
Task<string> FetchUserReadme(string githubUserLogin);
1111
Task<PortfolioViewModel> FetchCustomPortfolioFromFork(string username);
12-
Task<string> ChooseModel(string username);
12+
Task<string> ChooseModel(string username, string pageCursor = null);
1313
}
1414
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
namespace AwesomeGithubPortfolio.Core.Models.Responses;
22

3-
public record FollowerCollection(int TotalCount, List<PublicUser> Nodes)
3+
public record FollowCollection(int TotalCount, List<PublicUser> Nodes)
44
{
5+
public PageInfo PageInfo { get; set; }
56
public List<PublicUser> Shuffle()
67
{
78
return Nodes?.OrderBy(o => Random.Shared.Next()).ToList();
89
}
910
}
1011

11-
public record FollowingCollection(int TotalCount, List<PublicUser> Nodes);
12-
12+
public record PageInfo(string EndCursor, bool HasNextPage);
1313
public record PublicUser(string AvatarUrl, string Login);

src/AwesomeGithubPortfolio.Core/Models/GitHub/Responses/GitHubUser.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public class GitHubUser
1212
public DateTime CreatedAt { get; set; }
1313
public string Url { get; set; }
1414
public ContributionsCollection ContributionsCollection { get; set; }
15-
public FollowerCollection Followers { get; set; }
16-
public FollowingCollection Following { get; set; }
15+
public FollowCollection Followers { get; set; }
16+
public FollowCollection Following { get; set; }
1717
public Collection<Organization> Organizations { get; set; }
1818
public Collection<SocialAccount> SocialAccounts { get; set; }
1919
public Collection<Repository> PinnedItems { get; set; }

src/AwesomeGithubPortfolio.Core/Models/GitHub/Responses/Node.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{
33
public class Collection<T>
44
{
5+
public PageInfo PageInfo { get; set; }
56
public List<T> Nodes { get; set; }
67

78
}

src/AwesomeGithubPortfolio.Core/Services/GithubQueries.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,27 @@ public static class GithubOptions
1717
public const string OperationName = "userInfo";
1818

1919
public const string UserFollowers = @"
20-
query userInfo($login: String!) {
20+
query userInfo($login: String!, $after: String) {
2121
user(login: $login) {
22-
following (first: 100){
22+
following (first: 100, after: $after) {
23+
pageInfo {
24+
endCursor
25+
hasNextPage
26+
}
2327
nodes{
2428
login
2529
}
2630
}
2731
}
2832
}";
2933
public const string UserStarredRepositories = @"
30-
query userInfo($login: String!) {
34+
query userInfo($login: String!, $after: String) {
3135
user(login: $login) {
32-
starredRepositories {
36+
starredRepositories(first: 100, after: $after) {
37+
pageInfo {
38+
endCursor
39+
hasNextPage
40+
}
3341
nodes {
3442
nameWithOwner
3543
}

src/AwesomeGithubPortfolio.Core/Services/GithubUserService.cs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,36 @@ public async Task<GitHubUser> FetchUserData(string username)
5353
return user;
5454
}
5555

56-
public async Task<bool> UserHasStarred(string username)
56+
public async Task<bool> UserHasStarred(string username, string pageCursor)
5757
{
58-
var request = new DefaultRequest()
58+
do
5959
{
60-
Query = GithubOptions.UserStarredRepositories,
61-
OperationName = GithubOptions.OperationName,
62-
Variables = new { login = username }
63-
};
64-
var response = await _policy.ExecuteAndCaptureAsync(() => _client.PostAsJsonAsync("graphql", request, GithubOptions.DefaultJson));
60+
var request = new DefaultRequest()
61+
{
62+
Query = GithubOptions.UserStarredRepositories,
63+
OperationName = GithubOptions.OperationName,
64+
Variables = new { login = username, after = pageCursor }
65+
};
66+
var response = await _policy.ExecuteAndCaptureAsync(() => _client.PostAsJsonAsync("graphql", request, GithubOptions.DefaultJson));
6567

66-
if (response.Outcome != OutcomeType.Successful || !response.Result.IsSuccessStatusCode) return false;
68+
if (response.Outcome != OutcomeType.Successful || !response.Result.IsSuccessStatusCode) return false;
6769

68-
var userInfo =
69-
await JsonSerializer.DeserializeAsync<DefaultResponse<UserData>>(
70-
await response.Result.Content.ReadAsStreamAsync(), GithubOptions.DefaultJson);
70+
var userInfo = await JsonSerializer.DeserializeAsync<DefaultResponse<UserData>>(await response.Result.Content.ReadAsStreamAsync(), GithubOptions.DefaultJson);
71+
72+
if (userInfo.Data.User.StarredRepositories.Nodes.Any(a => a.NameWithOwner.Equals("brunobritodev/awesome-github-portfolio")))
73+
return true;
74+
75+
if (userInfo.Data.User.StarredRepositories.PageInfo.HasNextPage)
76+
{
77+
pageCursor = userInfo.Data.User.StarredRepositories.PageInfo.EndCursor;
78+
}
79+
else
80+
{
81+
pageCursor = null;
82+
}
83+
} while (pageCursor != null);
7184

72-
return userInfo.Data.User.StarredRepositories.Nodes.Any(a => a.NameWithOwner.Equals("brunobritodev/awesome-github-portfolio"));
85+
return false;
7386
}
7487

7588
public async Task<string> FetchUserReadme(string githubUserLogin)
@@ -96,26 +109,35 @@ public async Task<PortfolioViewModel> FetchCustomPortfolioFromFork(string userna
96109
return JsonSerializer.Deserialize<PortfolioViewModel>(data, GithubOptions.DefaultJson);
97110
}
98111

99-
public async Task<string> ChooseModel(string username)
112+
public async Task<string> ChooseModel(string username, string pageCursor)
100113
{
101-
var request = new DefaultRequest()
114+
do
102115
{
103-
Query = GithubOptions.UserFollowers,
104-
OperationName = GithubOptions.OperationName,
105-
Variables = new { login = username }
106-
};
107-
var response = await _policy.ExecuteAndCaptureAsync(() => _client.PostAsJsonAsync("graphql", request, GithubOptions.DefaultJson));
116+
var request = new DefaultRequest()
117+
{
118+
Query = GithubOptions.UserFollowers,
119+
OperationName = GithubOptions.OperationName,
120+
Variables = new { login = username, after = pageCursor }
121+
};
122+
var response = await _policy.ExecuteAndCaptureAsync(() => _client.PostAsJsonAsync("graphql", request, GithubOptions.DefaultJson));
108123

109-
if (response.Outcome != OutcomeType.Successful || !response.Result.IsSuccessStatusCode) return "gpt-4o-mini";
124+
if (response.Outcome != OutcomeType.Successful || !response.Result.IsSuccessStatusCode) return "gpt-4o-mini";
110125

111-
var userInfo =
112-
await JsonSerializer.DeserializeAsync<DefaultResponse<UserData>>(
113-
await response.Result.Content.ReadAsStreamAsync(), GithubOptions.DefaultJson);
126+
var userInfo = await JsonSerializer.DeserializeAsync<DefaultResponse<UserData>>(await response.Result.Content.ReadAsStreamAsync(), GithubOptions.DefaultJson);
114127

128+
var followingMe = userInfo?.Data?.User.Following.Nodes.Any(a => a.Login.Equals("brunobritodev"));
129+
if (followingMe is not null && followingMe.Value) return "gpt-4o";
115130

116-
var followingMe = userInfo?.Data?.User.Following.Nodes.Any(a => a.Login.Equals("brunobritodev"));
117-
if (followingMe is not null && followingMe.Value)
118-
return "gpt-4o";
131+
if (userInfo?.Data is not null & userInfo.Data.User.Following.PageInfo.HasNextPage)
132+
{
133+
pageCursor = userInfo?.Data?.User.Following.PageInfo.EndCursor;
134+
}
135+
else
136+
{
137+
pageCursor = null;
138+
}
139+
140+
} while (pageCursor != null);
119141

120142
return "gpt-4o-mini";
121143
}

0 commit comments

Comments
 (0)