@@ -77,14 +77,20 @@ class GitHub {
77
77
/**
78
78
* Fetches the repositories of the user specified by [user] .
79
79
*/
80
- Future <List <Repository >> userRepositories (String user, {String type: "owner" , int limit: 5000 , String sort: "full_name" , String direction: "asc" }) {
80
+ Future <List <Repository >> userRepositories (String user, {String type: "owner" , int limit, String sort: "full_name" , String direction: "asc" }) {
81
81
var params = {
82
- "per_page" : limit.toString (),
83
82
"sort" : sort,
84
83
"direction" : direction
85
84
};
86
- return getJSON ("/users/${user }/repos" , params: params).then ((List json) {
87
- return new List .from (json.map ((it) => Repository .fromJSON (this , it)));
85
+
86
+ var pages = limit != null ? (limit / 30 ).ceil () : null ;
87
+
88
+ return new PaginationHelper (this ).fetch ("GET" , "/users/${user }/repos" , pages: pages, params: params).then ((List <http.Response > responses) {
89
+ var list = < dynamic > [];
90
+ for (var response in responses) {
91
+ list.addAll (JSON .decode (response.body));
92
+ }
93
+ return new List .from (list.map ((it) => Repository .fromJSON (this , it)));
88
94
});
89
95
}
90
96
@@ -115,11 +121,10 @@ class GitHub {
115
121
*
116
122
* [name] is the organization name.
117
123
* [limit] is the maximum number of teams to provide.
118
- * Currently the highest you can go is 30.
119
124
*/
120
125
Future <List <Team >> teams (String name, [int limit]) {
121
126
var group = new FutureGroup <Team >();
122
- getJSON ("/orgs/${name }/teams" ).then ((teams) {
127
+ getJSON ("/orgs/${name }/teams?per_page=${ limit } " ).then ((teams) {
123
128
for (var team in teams) {
124
129
group.add (getJSON (team['url' ], convert: Team .fromJSON, statusCode: 200 , fail: (http.Response response) {
125
130
if (response.statusCode == 404 ) {
@@ -178,12 +183,17 @@ class GitHub {
178
183
* Gets a Repositories Releases.
179
184
*
180
185
* [slug] is the repository to fetch releases from.
181
- * [limit] is the maximum number of pages.
182
- * Currently the maximum limit is 100.
186
+ * [limit] is the maximum number of releases to show.
183
187
*/
184
- Future <List <Release >> releases (RepositorySlug slug, [int limit = 30 ]) {
185
- return getJSON ("/repos/${slug .fullName }/releases" , params: { "per_page" : limit }).then ((releases) {
186
- return copyOf (releases.map ((it) => Release .fromJSON (this , it)));
188
+ Future <List <Release >> releases (RepositorySlug slug, {int limit}) {
189
+ var pages = limit != null ? (limit / 30 ).ceil () : null ;
190
+
191
+ return new PaginationHelper (this ).fetch ("GET" , "/repos/${slug .fullName }/releases" , pages: pages, params: {}).then ((List <http.Response > responses) {
192
+ var list = < dynamic > [];
193
+ for (var response in responses) {
194
+ list.addAll (JSON .decode (response.body));
195
+ }
196
+ return new List .from (list.map ((it) => Repository .fromJSON (this , it)));
187
197
});
188
198
}
189
199
@@ -360,3 +370,52 @@ class GitHub {
360
370
}
361
371
}
362
372
}
373
+
374
+ class PaginationHelper {
375
+ final GitHub github;
376
+ final List <http.Response > responses;
377
+ final Completer <List <http.Response >> completer;
378
+
379
+ PaginationHelper (this .github) : responses = [], completer = new Completer <List <http.Response >>();
380
+
381
+ Future <List <http.Response >> fetch (String method, String path, {int pages, Map <String , String > headers, Map <String , dynamic > params, String body}) {
382
+ Future <http.Response > actualFetch (String realPath) {
383
+ return github.request (method, realPath, headers: headers, params: params, body: body);
384
+ }
385
+
386
+ void done () => completer.complete (responses);
387
+
388
+ var count = 0 ;
389
+
390
+ var handleResponse;
391
+ handleResponse = (http.Response response) {
392
+ count++ ;
393
+ responses.add (response);
394
+
395
+ if (! response.headers.containsKey ("link" )) {
396
+ done ();
397
+ return ;
398
+ }
399
+
400
+ var info = parseLinkHeader (response.headers['link' ]);
401
+
402
+ if (! info.containsKey ("next" )) {
403
+ done ();
404
+ return ;
405
+ }
406
+
407
+ if (pages != null && count == pages) {
408
+ done ();
409
+ return ;
410
+ }
411
+
412
+ var nextUrl = info['next' ];
413
+
414
+ actualFetch (nextUrl).then (handleResponse);
415
+ };
416
+
417
+ actualFetch (path).then (handleResponse);
418
+
419
+ return completer.future;
420
+ }
421
+ }
0 commit comments