From 1edc61edefdf4cf91751f5795e999e0f96c66f2d Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Sun, 16 Oct 2022 16:31:08 +0800 Subject: [PATCH] chore: github trending package --- packages/github_trending/.gitignore | 11 +++ packages/github_trending/CHANGELOG.md | 44 +++++++++ packages/github_trending/LICENSE | 21 ++++ packages/github_trending/README.md | 42 ++++++++ .../github_trending/analysis_options.yaml | 14 +++ .../example/github_trending_example.dart | 18 ++++ .../github_trending/lib/github_trending.dart | 2 + packages/github_trending/lib/src/api.dart | 61 ++++++++++++ packages/github_trending/lib/src/model.dart | 55 +++++++++++ packages/github_trending/lib/src/model.g.dart | 99 +++++++++++++++++++ packages/github_trending/pubspec.yaml | 17 ++++ .../test/github_trending_test.dart | 59 +++++++++++ pubspec.lock | 8 +- pubspec.yaml | 3 +- 14 files changed, 449 insertions(+), 5 deletions(-) create mode 100644 packages/github_trending/.gitignore create mode 100644 packages/github_trending/CHANGELOG.md create mode 100644 packages/github_trending/LICENSE create mode 100644 packages/github_trending/README.md create mode 100644 packages/github_trending/analysis_options.yaml create mode 100644 packages/github_trending/example/github_trending_example.dart create mode 100644 packages/github_trending/lib/github_trending.dart create mode 100644 packages/github_trending/lib/src/api.dart create mode 100644 packages/github_trending/lib/src/model.dart create mode 100644 packages/github_trending/lib/src/model.g.dart create mode 100644 packages/github_trending/pubspec.yaml create mode 100644 packages/github_trending/test/github_trending_test.dart diff --git a/packages/github_trending/.gitignore b/packages/github_trending/.gitignore new file mode 100644 index 0000000..50602ac --- /dev/null +++ b/packages/github_trending/.gitignore @@ -0,0 +1,11 @@ +# Files and directories created by pub +.dart_tool/ +.packages +# Remove the following pattern if you wish to check in your lock file +pubspec.lock + +# Conventional directory for build outputs +build/ + +# Directory created by dartdoc +doc/api/ diff --git a/packages/github_trending/CHANGELOG.md b/packages/github_trending/CHANGELOG.md new file mode 100644 index 0000000..234d737 --- /dev/null +++ b/packages/github_trending/CHANGELOG.md @@ -0,0 +1,44 @@ +# [1.1.0](https://github.com/git-touch/github-trending/compare/v1.0.0...v1.1.0) (2021-03-07) + +### Features + +- null safety ([40d285a](https://github.com/git-touch/github-trending/commit/40d285a511598545aa2c82199f94e1d51f6c256f)) + +# [1.0.0](https://github.com/git-touch/github-trending/compare/v0.3.0...v1.0.0) (2020-11-14) + +### Bug Fixes + +- decode with utf8 ([b13d07a](https://github.com/git-touch/github-trending/commit/b13d07a0ea6f98d434c95b1873508741af97d147)) + +# [0.3.0](https://github.com/git-touch/github-trending/compare/v0.2.0...v0.3.0) (2020-10-06) + +# [0.2.0](https://github.com/git-touch/github-trending/compare/v0.1.2...v0.2.0) (2020-02-09) + +### Bug Fixes + +- developer repo ([09223e2](https://github.com/git-touch/github-trending/commit/09223e238538ff6d9e304171c4dca6a9bc7b77e2)) + +## [0.1.2](https://github.com/git-touch/github-trending/compare/v0.1.1...v0.1.2) (2019-04-25) + +### Bug Fixes + +- language color match ([3967fcc](https://github.com/git-touch/github-trending/commit/3967fccc440ceee3cb8c57ab42070c8acfe4507b)) + +## [0.1.1](https://github.com/git-touch/github-trending/compare/v0.1.0...v0.1.1) (2019-03-12) + +### Bug Fixes + +- fix color matcher for colors like #ccc ([3222ed6](https://github.com/git-touch/github-trending/commit/3222ed6f261d0f3069d761b7d7229f7c8c888a51)) + +# [0.1.0](https://github.com/git-touch/github-trending/compare/edb71b7a5fe1f8bcf6662ac20888fc795159137a...v0.1.0) (2019-03-06) + +### Bug Fixes + +- language node null ([9691db2](https://github.com/git-touch/github-trending/commit/9691db2eebad85e2b4e3ff44c91522086294bca8)) +- star and fork number with comma ([4a99551](https://github.com/git-touch/github-trending/commit/4a995516409881f259875b2491a12b312d2125e4)) + +### Features + +- add description HTML field, remove anchor tag of description ([922ecb1](https://github.com/git-touch/github-trending/commit/922ecb194d19d9536436498d642f16c45c9d58c2)) +- add since and language params ([ab7a7f0](https://github.com/git-touch/github-trending/commit/ab7a7f03d61a588564ea3c2a4a0500e2643ac434)) +- basic implemetation ([edb71b7](https://github.com/git-touch/github-trending/commit/edb71b7a5fe1f8bcf6662ac20888fc795159137a)) diff --git a/packages/github_trending/LICENSE b/packages/github_trending/LICENSE new file mode 100644 index 0000000..6fe60e5 --- /dev/null +++ b/packages/github_trending/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Rongjian Zhang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/github_trending/README.md b/packages/github_trending/README.md new file mode 100644 index 0000000..2f6c0a4 --- /dev/null +++ b/packages/github_trending/README.md @@ -0,0 +1,42 @@ +# github_trending + +[![pub](https://img.shields.io/pub/v/github_trending.svg)](https://pub.dev/packages/github_trending) +[![test](https://github.com/pd4d10/github-trending/workflows/test/badge.svg)](https://github.com/pd4d10/github-trending/actions?query=workflow:test) + +A Dart library to get GitHub trending repositories and developers via [github-trending-api](https://github.com/huchenme/github-trending-api). + +## Installation + +Add `github_trending` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/packages-and-plugins/using-packages) + +## Usage + +```dart +import 'package:github_trending/github_trending.dart'; + +void main() async { + final trending = GithubTrending(prefix: 'https://gtrend.yapie.me'); + + // get trending repositories + var repos = await trending.getTrendingRepositories(); + print(repos[0].name); + + // specify time period + var weeklyRepos = await trending.getTrendingRepositories(since: 'weekly'); + print(weeklyRepos[0].name); + + // specify language + var dartRepos = await trending.getTrendingRepositories(language: 'dart'); + print(dartRepos[0].language); // Dart + print(dartRepos[0].languageColor); // #00B4AB +} + +``` + +## Credits + +- [github-trending-api](https://github.com/huchenme/github-trending-api) + +## License + +MIT diff --git a/packages/github_trending/analysis_options.yaml b/packages/github_trending/analysis_options.yaml new file mode 100644 index 0000000..a686c1b --- /dev/null +++ b/packages/github_trending/analysis_options.yaml @@ -0,0 +1,14 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: package:pedantic/analysis_options.yaml + +# For lint rules and documentation, see http://dart-lang.github.io/linter/lints. +# Uncomment to specify additional rules. +# linter: +# rules: +# - camel_case_types + +analyzer: +# exclude: +# - path/to/excluded/files/** diff --git a/packages/github_trending/example/github_trending_example.dart b/packages/github_trending/example/github_trending_example.dart new file mode 100644 index 0000000..c513597 --- /dev/null +++ b/packages/github_trending/example/github_trending_example.dart @@ -0,0 +1,18 @@ +import 'package:github_trending/github_trending.dart'; + +void main() async { + final trending = GithubTrending(); + + // get trending repositories + var repos = await trending.getTrendingRepositories(); + print(repos[0].name); + + // specify time period + var weeklyRepos = await trending.getTrendingRepositories(since: 'weekly'); + print(weeklyRepos[0].name); + + // specify language + var dartRepos = await trending.getTrendingRepositories(language: 'dart'); + print(dartRepos[0].language); // Dart + print(dartRepos[0].languageColor); // #00B4AB +} diff --git a/packages/github_trending/lib/github_trending.dart b/packages/github_trending/lib/github_trending.dart new file mode 100644 index 0000000..ab49d9c --- /dev/null +++ b/packages/github_trending/lib/github_trending.dart @@ -0,0 +1,2 @@ +export 'src/model.dart'; +export 'src/api.dart'; diff --git a/packages/github_trending/lib/src/api.dart b/packages/github_trending/lib/src/api.dart new file mode 100644 index 0000000..79d33a9 --- /dev/null +++ b/packages/github_trending/lib/src/api.dart @@ -0,0 +1,61 @@ +import 'dart:convert'; +import 'package:github_trending/src/model.dart'; +import 'package:http/http.dart' as http; + +class TrendingRepositoryPrimaryLanguage { + String? name; + String? color; + TrendingRepositoryPrimaryLanguage({this.name, this.color}); +} + +class GithubTrending { + String prefix; + + GithubTrending({this.prefix = 'https://ghapi.huchen.dev'}); + + Future _getJson(Uri url) async { + final res = await http.get(url); + return json.decode(utf8.decode(res.bodyBytes)); + } + + /// Get trending repositories + /// + /// https://github.com/huchenme/github-trending-api#trending-repositories + Future> getTrendingRepositories({ + /// daily, weekly, monthly + String? since, + String? language, + String? spokenLanguageCode, + }) async { + final res = await _getJson(Uri.parse('$prefix/repositories').replace( + queryParameters: { + if (since != null) 'since': since, + if (language != null) 'language': language, + if (spokenLanguageCode != null) + 'spoken_language_code': spokenLanguageCode + }, + )); + return (res as List) + .map((v) => GithubTrendingRepository.fromJson(v)) + .toList(); + } + + /// Get trending developers + /// + /// https://github.com/huchenme/github-trending-api#trending-developers + Future> getTrendingDevelopers({ + /// daily, weekly, monthly + String? since, + String? language, + }) async { + final res = await _getJson(Uri.parse('$prefix/developers').replace( + queryParameters: { + if (since != null) 'since': since, + if (language != null) 'language': language, + }, + )); + return (res as List) + .map((v) => GithubTrendingDeveloper.fromJson(v)) + .toList(); + } +} diff --git a/packages/github_trending/lib/src/model.dart b/packages/github_trending/lib/src/model.dart new file mode 100644 index 0000000..0d0192a --- /dev/null +++ b/packages/github_trending/lib/src/model.dart @@ -0,0 +1,55 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'model.g.dart'; + +@JsonSerializable() +class GithubTrendingRepository { + String? author; + String? name; + String? avatar; + String? url; + String? description; + String? language; + String? languageColor; + int? stars; + int? forks; + int? currentPeriodStars; + List? builtBy; + GithubTrendingRepository(); + factory GithubTrendingRepository.fromJson(Map json) => + _$GithubTrendingRepositoryFromJson(json); +} + +@JsonSerializable() +class GithubTrendingRepositoryBuiltBy { + String? href; + String? avatar; + String? username; + GithubTrendingRepositoryBuiltBy(); + factory GithubTrendingRepositoryBuiltBy.fromJson(Map json) => + _$GithubTrendingRepositoryBuiltByFromJson(json); +} + +@JsonSerializable() +class GithubTrendingDeveloper { + String? username; + String? name; + String? type; + String? url; + String? avatar; + GithubTrendingDeveloperRepository? repo; + GithubTrendingDeveloper(); + factory GithubTrendingDeveloper.fromJson(Map json) => + _$GithubTrendingDeveloperFromJson(json); +} + +@JsonSerializable() +class GithubTrendingDeveloperRepository { + String? name; + String? description; + String? url; + GithubTrendingDeveloperRepository(); + factory GithubTrendingDeveloperRepository.fromJson( + Map json) => + _$GithubTrendingDeveloperRepositoryFromJson(json); +} diff --git a/packages/github_trending/lib/src/model.g.dart b/packages/github_trending/lib/src/model.g.dart new file mode 100644 index 0000000..ca1008c --- /dev/null +++ b/packages/github_trending/lib/src/model.g.dart @@ -0,0 +1,99 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +GithubTrendingRepository _$GithubTrendingRepositoryFromJson( + Map json) { + return GithubTrendingRepository() + ..author = json['author'] as String? + ..name = json['name'] as String? + ..avatar = json['avatar'] as String? + ..url = json['url'] as String? + ..description = json['description'] as String? + ..language = json['language'] as String? + ..languageColor = json['languageColor'] as String? + ..stars = json['stars'] as int? + ..forks = json['forks'] as int? + ..currentPeriodStars = json['currentPeriodStars'] as int? + ..builtBy = (json['builtBy'] as List?) + ?.map((e) => + GithubTrendingRepositoryBuiltBy.fromJson(e as Map)) + .toList(); +} + +Map _$GithubTrendingRepositoryToJson( + GithubTrendingRepository instance) => + { + 'author': instance.author, + 'name': instance.name, + 'avatar': instance.avatar, + 'url': instance.url, + 'description': instance.description, + 'language': instance.language, + 'languageColor': instance.languageColor, + 'stars': instance.stars, + 'forks': instance.forks, + 'currentPeriodStars': instance.currentPeriodStars, + 'builtBy': instance.builtBy, + }; + +GithubTrendingRepositoryBuiltBy _$GithubTrendingRepositoryBuiltByFromJson( + Map json) { + return GithubTrendingRepositoryBuiltBy() + ..href = json['href'] as String? + ..avatar = json['avatar'] as String? + ..username = json['username'] as String?; +} + +Map _$GithubTrendingRepositoryBuiltByToJson( + GithubTrendingRepositoryBuiltBy instance) => + { + 'href': instance.href, + 'avatar': instance.avatar, + 'username': instance.username, + }; + +GithubTrendingDeveloper _$GithubTrendingDeveloperFromJson( + Map json) { + return GithubTrendingDeveloper() + ..username = json['username'] as String? + ..name = json['name'] as String? + ..type = json['type'] as String? + ..url = json['url'] as String? + ..avatar = json['avatar'] as String? + ..repo = json['repo'] == null + ? null + : GithubTrendingDeveloperRepository.fromJson( + json['repo'] as Map); +} + +Map _$GithubTrendingDeveloperToJson( + GithubTrendingDeveloper instance) => + { + 'username': instance.username, + 'name': instance.name, + 'type': instance.type, + 'url': instance.url, + 'avatar': instance.avatar, + 'repo': instance.repo, + }; + +GithubTrendingDeveloperRepository _$GithubTrendingDeveloperRepositoryFromJson( + Map json) { + return GithubTrendingDeveloperRepository() + ..name = json['name'] as String? + ..description = json['description'] as String? + ..url = json['url'] as String?; +} + +Map _$GithubTrendingDeveloperRepositoryToJson( + GithubTrendingDeveloperRepository instance) => + { + 'name': instance.name, + 'description': instance.description, + 'url': instance.url, + }; diff --git a/packages/github_trending/pubspec.yaml b/packages/github_trending/pubspec.yaml new file mode 100644 index 0000000..0a45ad2 --- /dev/null +++ b/packages/github_trending/pubspec.yaml @@ -0,0 +1,17 @@ +name: github_trending +description: A library to get GitHub trending repositories and developers, with languages and period options. +version: 1.1.0 +homepage: https://github.com/git-touch/github-trending + +environment: + sdk: ">=2.12.0 <3.0.0" + +dependencies: + http: ^0.13.0 + json_annotation: ^4.0.0 + +dev_dependencies: + pedantic: ^1.11.0 + test: ^1.16.5 + build_runner: ^1.11.5 + json_serializable: ^4.0.2 diff --git a/packages/github_trending/test/github_trending_test.dart b/packages/github_trending/test/github_trending_test.dart new file mode 100644 index 0000000..be79ad2 --- /dev/null +++ b/packages/github_trending/test/github_trending_test.dart @@ -0,0 +1,59 @@ +import 'package:github_trending/github_trending.dart'; +import 'package:test/test.dart'; + +// https://github.com/huchenme/github-trending-api/issues/130#issuecomment-703483762 +final trending = GithubTrending(prefix: 'https://gtrend.yapie.me'); + +void main() { + group('repositories', () { + List? items; + + setUpAll(() async { + items = await trending.getTrendingRepositories(); + }); + + test('has data', () { + expect(items, isList); + }); + + test('owner, name are not null', () { + items!.forEach((item) { + expect(item.author, isNotNull); + expect(item.name, isNotNull); + }); + }); + + test('star and fork count', () { + // make sure at least one item has star or fork + // to ensure no parse error + var itemHasStar = items!.where((item) => item.stars != null); + expect(itemHasStar, isNotEmpty); + + var itemHasFork = items!.where((item) => item.forks != null); + expect(itemHasFork, isNotEmpty); + }); + + test('language color', () { + items!.forEach((item) { + if (item.languageColor != null) { + expect( + RegExp(r'#[0-9a-fA-F]{3,6}').hasMatch(item.languageColor!), + isTrue, + ); + } + }); + }); + }); + + group('developers', () { + List? items; + + setUpAll(() async { + items = await trending.getTrendingDevelopers(); + }); + + test('has data', () { + expect(items, isList); + }); + }); +} diff --git a/pubspec.lock b/pubspec.lock index 9b9109a..ddfe763 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,7 +21,7 @@ packages: path: "../ant-design-mobile-flutter" relative: true source: path - version: "0.0.1" + version: "0.1.0" args: dependency: transitive description: @@ -339,9 +339,9 @@ packages: github_trending: dependency: "direct main" description: - name: github_trending - url: "https://pub.dartlang.org" - source: hosted + path: "packages/github_trending" + relative: true + source: path version: "1.1.0" glob: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index db6bda7..e085e03 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,8 @@ dependencies: path: ./packages/gql_github gql_gitlab: path: ./packages/gql_gitlab + github_trending: + path: ./packages/github_trending cupertino_icons: ferry: ferry_flutter: @@ -46,7 +48,6 @@ dependencies: flutter_svg: flutter_vector_icons: github: - github_trending: gql: gql_http_link: http: