Skip to content

Commit

Permalink
Add ip info fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
0xConsumer committed Feb 9, 2024
1 parent b86cd26 commit 37dc336
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ migrate_working_dir/
# generated files
**/*.g.dart
**/*.freezed.dart
**/*.mapper.dart
**/*.gen.dart
**/libclash.so
**/libclash.h
Expand Down
2 changes: 2 additions & 0 deletions lib/features/proxy/data/proxy_data_providers.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:hiddify/core/http_client/http_client_provider.dart';
import 'package:hiddify/features/proxy/data/proxy_repository.dart';
import 'package:hiddify/singbox/service/singbox_service_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
Expand All @@ -8,5 +9,6 @@ part 'proxy_data_providers.g.dart';
ProxyRepository proxyRepository(ProxyRepositoryRef ref) {
return ProxyRepositoryImpl(
singbox: ref.watch(singboxServiceProvider),
client: ref.watch(httpClientProvider),
);
}
38 changes: 37 additions & 1 deletion lib/features/proxy/data/proxy_repository.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'package:fpdart/fpdart.dart';
import 'package:hiddify/core/http_client/dio_http_client.dart';
import 'package:hiddify/core/utils/exception_handler.dart';
import 'package:hiddify/features/proxy/model/ip_info_entity.dart';
import 'package:hiddify/features/proxy/model/proxy_entity.dart';
import 'package:hiddify/features/proxy/model/proxy_failure.dart';
import 'package:hiddify/singbox/service/singbox_service.dart';
import 'package:hiddify/utils/custom_loggers.dart';

abstract interface class ProxyRepository {
Stream<Either<ProxyFailure, List<ProxyGroupEntity>>> watchProxies();
TaskEither<ProxyFailure, IpInfo> getCurrentIpInfo();
TaskEither<ProxyFailure, Unit> selectProxy(
String groupTag,
String outboundTag,
Expand All @@ -17,13 +20,18 @@ abstract interface class ProxyRepository {
class ProxyRepositoryImpl
with ExceptionHandler, InfraLogger
implements ProxyRepository {
ProxyRepositoryImpl({required this.singbox});
ProxyRepositoryImpl({
required this.singbox,
required this.client,
});

final SingboxService singbox;
final DioHttpClient client;

@override
Stream<Either<ProxyFailure, List<ProxyGroupEntity>>> watchProxies() {
return singbox.watchOutbounds().map((event) {
print("outbounds: $event");
final groupWithSelected = {
for (final group in event) group.tag: group.selected,
};
Expand Down Expand Up @@ -76,4 +84,32 @@ class ProxyRepositoryImpl
ProxyUnexpectedFailure.new,
);
}

final Map<String, IpInfo Function(Map<String, dynamic> response)>
_ipInfoSources = {
"https://ipapi.co/json/": IpInfo.fromIpApiCoJson,
"https://ipinfo.io/json/": IpInfo.fromIpInfoIoJson,
};

@override
TaskEither<ProxyFailure, IpInfo> getCurrentIpInfo() {
return TaskEither.tryCatch(
() async {
for (final source in _ipInfoSources.entries) {
try {
loggy.debug("getting current ip info using [${source.key}]");
final response = await client.get<Map<String, dynamic>>(source.key);
if (response.statusCode == 200 && response.data != null) {
return source.value(response.data!);
}
} catch (e) {
loggy.debug("failed getting ip info using [${source.key}]", e);
continue;
}
}
throw const ProxyFailure.unexpected();
},
ProxyUnexpectedFailure.new,
);
}
}
70 changes: 70 additions & 0 deletions lib/features/proxy/model/ip_info_entity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:dart_mappable/dart_mappable.dart';

part 'ip_info_entity.mapper.dart';

@MappableClass()
class IpInfo with IpInfoMappable {
const IpInfo({
required this.ip,
required this.countryCode,
required this.region,
required this.city,
this.timezone,
this.asn,
this.org,
});

final String ip;
final String countryCode;
final String region;
final String city;
final String? timezone;
final String? asn;
final String? org;

static IpInfo fromIpInfoIoJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country": final String country,
"region": final String region,
"city": final String city,
"timezone": final String timezone,
"org": final String org,
} =>
IpInfo(
ip: ip,
countryCode: country,
region: region,
city: city,
timezone: timezone,
org: org,
),
_ => throw const FormatException("invalid json"),
};
}

static IpInfo fromIpApiCoJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country_code": final String countryCode,
"region": final String region,
"city": final String city,
"timezone": final String timezone,
"asn": final String asn,
"org": final String org,
} =>
IpInfo(
ip: ip,
countryCode: countryCode,
region: region,
city: city,
timezone: timezone,
asn: asn,
org: org,
),
_ => throw const FormatException("invalid json"),
};
}
}
24 changes: 24 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.8"
dart_mappable:
dependency: "direct main"
description:
name: dart_mappable
sha256: "7b6d38ae95f1ae8ffa65df9a5464f14b56c2de94699a035202ca4cd3a0ba249e"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
dart_mappable_builder:
dependency: "direct dev"
description:
name: dart_mappable_builder
sha256: "98c058f7e80a98ea42d357d888ed1648d96bedac8b16872b58fc7024faefcdfe"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
dart_style:
dependency: transitive
description:
Expand Down Expand Up @@ -1538,6 +1554,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.1"
type_plus:
dependency: transitive
description:
name: type_plus
sha256: "2e33cfac2e129297d5874567bdf7587502ec359881e9318551e014d91b02f84a"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
typed_data:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dependencies:
dio_smart_retry: ^6.0.0
cupertino_http: ^1.3.0
wolt_modal_sheet: ^0.4.0
dart_mappable: ^4.2.0

dev_dependencies:
flutter_test:
Expand All @@ -86,6 +87,7 @@ dev_dependencies:
flutter_gen_runner: ^5.4.0
go_router_builder: ^2.4.1
dependency_validator: ^3.2.3
dart_mappable_builder: ^4.2.0

flutter:
uses-material-design: true
Expand Down

0 comments on commit 37dc336

Please sign in to comment.