Skip to content

Commit

Permalink
Feat:使用OpenL进行翻译
Browse files Browse the repository at this point in the history
  • Loading branch information
honjow committed May 29, 2021
1 parent 66ee4ec commit 9e94885
Show file tree
Hide file tree
Showing 18 changed files with 280 additions and 44 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ app.*.symbols
app.*.map.json

# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
/ios/build/
/ios/Podfile.lock
/ios/Runner/GoogleService-Info.plist
Expand All @@ -56,3 +56,4 @@ app.*.map.json
/test/
/linux/
.fvm
/assets/openl.json
4 changes: 4 additions & 0 deletions assets/openl.json.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 填入自己的OpenL apikey (https://openl.club/), 并修改文件名为 openl.json
{
"apikey": "abcabcacb"
}
7 changes: 7 additions & 0 deletions jsons/openl_translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"status?": true,
"text?": "HTML elements",
"result?": "HTML元素",
"source_lang?": "auto",
"target_lang?": "zh"
}
2 changes: 1 addition & 1 deletion lib/models/dns_config.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/foundation.dart';

import 'dns_cache.dart';
import 'dns_cache.dart';

@immutable
Expand Down
1 change: 0 additions & 1 deletion lib/models/gallery_comment.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart';

import 'gallery_comment_span.dart';

@immutable
Expand Down
5 changes: 2 additions & 3 deletions lib/models/gallery_item.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'package:flutter/foundation.dart';

import 'gallery_comment.dart';
import 'gallery_preview.dart';
import 'gallery_torrent.dart';
import 'simple_tag.dart';
import 'tag_group.dart';
import 'gallery_comment.dart';
import 'gallery_preview.dart';

@immutable
class GalleryItem {
Expand Down
35 changes: 18 additions & 17 deletions lib/models/index.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
export 'advance_search.dart';
export 'auto_lock.dart';
export 'cache_config.dart';
export 'local_fav.dart';
export 'eh_config.dart';
export 'simple_tag.dart';
export 'commit_vote_res.dart';
export 'dns_cache.dart';
export 'dns_config.dart';
export 'download_config.dart';
export 'auto_lock.dart';
export 'gallery_item.dart';
export 'download_task_info.dart';
export 'eh_config.dart';
export 'favcat.dart';
export 'dns_config.dart';
export 'gallery_cache.dart';
export 'gallery_comment.dart';
export 'gallery_comment_span.dart';
export 'gallery_item.dart';
export 'gallery_preview.dart';
export 'gallery_comment.dart';
export 'openl_translation.dart';
export 'gallery_tag.dart';
export 'gallery_torrent.dart';
export 'local_fav.dart';
export 'profile.dart';
export 'simple_tag.dart';
export 'tab_config.dart';
export 'dns_cache.dart';
export 'tab_item.dart';
export 'tag_group.dart';
export 'user.dart';
export 'download_config.dart';
export 'gallery_torrent.dart';
export 'advance_search.dart';
export 'tag_group.dart';
export 'tab_config.dart';
export 'favcat.dart';
export 'cache_config.dart';
export 'gallery_preview.dart';
export 'profile.dart';
1 change: 0 additions & 1 deletion lib/models/local_fav.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart';

import 'gallery_item.dart';

@immutable
Expand Down
66 changes: 66 additions & 0 deletions lib/models/openl_translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:flutter/foundation.dart';


@immutable
class OpenlTranslation {

const OpenlTranslation({
this.status,
this.text,
this.result,
this.sourceLang,
this.targetLang,
});

final bool? status;
final String? text;
final String? result;
final String? sourceLang;
final String? targetLang;

factory OpenlTranslation.fromJson(Map<String,dynamic> json) => OpenlTranslation(
status: json['status'] != null ? json['status'] as bool : null,
text: json['text'] != null ? json['text'] as String : null,
result: json['result'] != null ? json['result'] as String : null,
sourceLang: json['source_lang'] != null ? json['source_lang'] as String : null,
targetLang: json['target_lang'] != null ? json['target_lang'] as String : null
);

Map<String, dynamic> toJson() => {
'status': status,
'text': text,
'result': result,
'source_lang': sourceLang,
'target_lang': targetLang
};

OpenlTranslation clone() => OpenlTranslation(
status: status,
text: text,
result: result,
sourceLang: sourceLang,
targetLang: targetLang
);


OpenlTranslation copyWith({
bool? status,
String? text,
String? result,
String? sourceLang,
String? targetLang
}) => OpenlTranslation(
status: status ?? this.status,
text: text ?? this.text,
result: result ?? this.result,
sourceLang: sourceLang ?? this.sourceLang,
targetLang: targetLang ?? this.targetLang,
);

@override
bool operator ==(Object other) => identical(this, other)
|| other is OpenlTranslation && status == other.status && text == other.text && result == other.result && sourceLang == other.sourceLang && targetLang == other.targetLang;

@override
int get hashCode => status.hashCode ^ text.hashCode ^ result.hashCode ^ sourceLang.hashCode ^ targetLang.hashCode;
}
1 change: 0 additions & 1 deletion lib/models/tab_config.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart';

import 'tab_item.dart';

@immutable
Expand Down
1 change: 0 additions & 1 deletion lib/models/tag_group.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart';

import 'gallery_tag.dart';

@immutable
Expand Down
1 change: 0 additions & 1 deletion lib/models/user.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/foundation.dart';

import 'favcat.dart';

@immutable
Expand Down
23 changes: 17 additions & 6 deletions lib/pages/gallery/view/translator_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:fehviewer/const/theme_colors.dart';
import 'package:fehviewer/utils/logger.dart';
import 'package:fehviewer/utils/openl/translator_helper.dart';
import 'package:fehviewer/utils/vibrate.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -36,13 +37,22 @@ class TranslatorDialogView extends StatefulWidget {
class _TranslatorDialogViewState extends State<TranslatorDialogView> {
final GoogleTranslator _translator = GoogleTranslator();

late Future<Translation?> _future;
late Future<String?> _future;

Future<Translation?> _getTrans() async {
Future<String?> _getTrans() async {
try {
final Translation _trans =
await _translator.translate(widget.inputText, to: 'zh-cn');
return _trans;
return _trans.text;
} catch (e, stack) {
logger.e('$e\n$stack');
return null;
}
}

Future<String?> _getTransOpenL() async {
try {
return await TranslatorHelper.translateText(widget.inputText, to: 'zh');
} catch (e, stack) {
logger.e('$e\n$stack');
return null;
Expand All @@ -52,12 +62,13 @@ class _TranslatorDialogViewState extends State<TranslatorDialogView> {
@override
void initState() {
super.initState();
_future = _getTrans();
// _future = _getTrans();
_future = _getTransOpenL();
}

@override
Widget build(BuildContext context) {
return FutureBuilder<Translation?>(
return FutureBuilder<String?>(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Expand All @@ -81,7 +92,7 @@ class _TranslatorDialogViewState extends State<TranslatorDialogView> {
child: Container(
width: double.infinity,
child: Text(
_trans?.text ?? '',
_trans ?? '',
textAlign: TextAlign.start,
style: TextStyle(
height: 1.5,
Expand Down
56 changes: 56 additions & 0 deletions lib/utils/openl/language.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/// Language object with name and code (ISO)
class Language {
Language(this.code, this.name);
final String name;
final String code;

@override
String toString() => name;
}

/// Language list containing all languages supported by openl Translate API
class LanguageList {
static final Map<String, String> _langs = {
'auto': 'Automatic',
'zh': 'Chinese',
'en': 'English',
'de': 'German',
'fr': 'French',
'it': 'Italian',
'ja': 'Japanese',
'es': 'Spanish',
'nl': 'Dutch',
'pl': 'Polish',
'pt': 'Portuguese',
'ru': 'Russian',
};

Language operator [](String code) {
code = code.toLowerCase();
if (_langs.containsKey(code)) {
return Language(code, _langs[code]!);
}
throw LanguageNotSupportedException('$code is not a supported language.');
}

static bool contains(String codeOrLang) {
if (_langs.containsKey(codeOrLang) ||
_langs.containsValue(codeOrLang.toCamelCase())) {
return true;
}
return false;
}
}

class LanguageNotSupportedException implements Exception {
LanguageNotSupportedException(String lang)
: msg = '$lang is not a supported language.';

final String msg;
}

extension _CamelCase on String {
String toCamelCase() {
return '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
}
}
50 changes: 50 additions & 0 deletions lib/utils/openl/openl_translator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'dart:convert' show jsonDecode, jsonEncode;

import 'package:fehviewer/models/base/eh_models.dart';
import 'package:fehviewer/utils/openl/language.dart';

import 'package:http/http.dart' as http;

const String _baseUrl = 'api.openl.club';

class OpenLTranslator {
OpenLTranslator({required this.apikey});

final String apikey;

Future<OpenlTranslation> translate(
String sourceText, {
String from = 'auto',
String to = 'en',
String service = 'deepl',
}) async {
for (final String each in [from, to]) {
if (!LanguageList.contains(each)) {
throw LanguageNotSupportedException(each);
}
}

final String _path = '/services/$service/translate';

final Map<String, String> reqMap = {
'apikey': apikey,
'text': sourceText,
'source_lang': from,
'target_lang': to,
};

final Uri url = Uri.https(_baseUrl, _path);
final data = await http.post(url, body: jsonEncode(reqMap));

if (data.statusCode != 200) {
throw http.ClientException('Error ${data.statusCode}: ${data.body}', url);
}

final jsonData = jsonDecode(data.body);
if (jsonData == null) {
throw http.ClientException('Error: Can\'t parse json data');
}

return OpenlTranslation.fromJson(jsonData);
}
}
43 changes: 43 additions & 0 deletions lib/utils/openl/translator_helper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'dart:async';
import 'dart:convert';

import 'package:fehviewer/models/openl_translation.dart';
import 'package:fehviewer/utils/logger.dart';
import 'package:fehviewer/utils/openl/openl_translator.dart';
import 'package:flutter/services.dart';

class TranslatorHelper {
static Future<String> getApikey() async {
final String openl = await rootBundle.loadString('assets/openl.json');
final openlJson = json.decode(openl);
return openlJson['apikey'] ?? '';
}

static Future<OpenlTranslation> translate(
String sourceText, {
String from = 'auto',
String to = 'en',
String service = 'deepl',
}) async {
final String apikey = await getApikey();

logger.v('apikey $apikey');

final OpenLTranslator openLTranslator = OpenLTranslator(apikey: apikey);
return openLTranslator.translate(sourceText, from: from, to: to);
}

static Future<String> translateText(
String sourceText, {
String from = 'auto',
String to = 'en',
String service = 'deepl',
}) async {
final OpenlTranslation rult =
await translate(sourceText, from: from, to: to);

logger.v(rult.toJson());

return rult.result ?? '';
}
}
Loading

0 comments on commit 9e94885

Please sign in to comment.