Skip to content

Commit

Permalink
Merge pull request #510 from project-violet/rf-5
Browse files Browse the repository at this point in the history
Refactor 005: Remove `tuple` package
  • Loading branch information
violet-dev authored Sep 8, 2024
2 parents bc05da4 + 42a364d commit 3e09877
Show file tree
Hide file tree
Showing 59 changed files with 744 additions and 853 deletions.
6 changes: 2 additions & 4 deletions violet/lib/cert/cert_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import 'dart:math';
import 'dart:typed_data';

import 'package:pointycastle/export.dart';
import 'package:tuple/tuple.dart';

// https://github.com/bcgit/pc-dart/blob/master/tutorials/rsa.md
class CertUtil {
static Tuple2<RSAPublicKey, RSAPrivateKey> createRSAKeyPair() {
static (RSAPublicKey, RSAPrivateKey) createRSAKeyPair() {
final secureRandom = SecureRandom('Fortuna')
..seed(KeyParameter(Uint8List.fromList(
List.generate(32, (index) => Random().nextInt(256)))));
Expand All @@ -20,8 +19,7 @@ class CertUtil {
secureRandom));
final pair = keyGen.generateKeyPair();

return Tuple2<RSAPublicKey, RSAPrivateKey>(
pair.publicKey as RSAPublicKey, pair.privateKey as RSAPrivateKey);
return (pair.publicKey as RSAPublicKey, pair.privateKey as RSAPrivateKey);
}

static Uint8List sign(RSAPrivateKey privateKey, Uint8List dataToSign) {
Expand Down
24 changes: 12 additions & 12 deletions violet/lib/component/eh/eh_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:html_unescape/html_unescape.dart';
import 'package:intl/intl.dart';
import 'package:tuple/tuple.dart';
import 'package:violet/log/log.dart';

class EHArticle {
Expand Down Expand Up @@ -35,7 +34,7 @@ class EHArticle {
List<String>? female;
List<String>? misc;

List<Tuple3<DateTime, String, String>>? comment;
List<(DateTime, String, String)>? comment;
List<String>? imageLink;
}

Expand Down Expand Up @@ -158,7 +157,7 @@ class EHParser {
if (info.containsKey('misc:')) article.misc = info['misc:'];

var nodeComments = h.querySelectorAll("div[id='cdiv'] > div.c1");
var comments = <Tuple3<DateTime, String, String>>[];
var comments = <(DateTime, String, String)>[];

var hu = HtmlUnescape();
var df = DateFormat('dd MMMM yyyy, H:m');
Expand All @@ -171,17 +170,18 @@ class EHParser {
.querySelector('div.c6')!
.innerHtml
.replaceAll('<br>', '\r\n'));
comments.add(Tuple3<DateTime, String, String>(
df.parse(
date
.substring(0, date.indexOf(' by'))
.substring('Posted on '.length),
true),
author,
contents));
comments.add((
df.parse(
date
.substring(0, date.indexOf(' by'))
.substring('Posted on '.length),
true),
author,
contents
));
}

comments.sort((x, y) => x.item1.compareTo(y.item1));
comments.sort((x, y) => x.$1.compareTo(y.$1));
article.comment = comments;

return article;
Expand Down
2 changes: 1 addition & 1 deletion violet/lib/component/hentai.dart
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ class HentaiManager {
case 'Hitomi':
{
var urls = await HitomiManager.getImageList(qr.id().toString());
if (urls.item1.isEmpty || urls.item2.isEmpty) break;
if (urls.$1.isEmpty || urls.$2.isEmpty) break;
return HitomiImageProvider(urls, qr.id().toString());
}

Expand Down
12 changes: 7 additions & 5 deletions violet/lib/component/hisoki/hisoki_getter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

import 'dart:convert';

import 'package:tuple/tuple.dart';
import 'package:violet/component/hisoki/hisoki_hash.dart';
import 'package:violet/network/wrapper.dart' as http;

class HisokiGetter {
static Future<List<Tuple3<String, double, double>>?> getImages(int id) async {
static Future<List<(String, double, double)>?> getImages(int id) async {
var hash = HisokiHash.getHash('$id');

if (hash == null) return null;
Expand All @@ -18,11 +17,14 @@ class HisokiGetter {
var sl = info['sl'] as List<dynamic>;
var il = info['il'] as List<dynamic>;

var result = <Tuple3<String, double, double>>[];
var result = <(String, double, double)>[];

for (var i = 0; i < il.length; i++) {
result.add(Tuple3<String, double, double>('${il[i]}.webp',
(sl[i]['w'] as int).toDouble(), (sl[i]['h'] as int).toDouble()));
result.add((
'${il[i]}.webp',
(sl[i]['w'] as int).toDouble(),
(sl[i]['h'] as int).toDouble()
));
}

return result;
Expand Down
10 changes: 4 additions & 6 deletions violet/lib/component/hisoki/hisoki_provider.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// This source code is a part of Project Violet.
// Copyright (C) 2021. violet-team. Licensed under the Apache-2.0 License.

import 'package:tuple/tuple.dart';
import 'package:violet/component/image_provider.dart';

class HisokiImageProvider extends VioletImageProvider {
int id;
List<Tuple3<String, double, double>> infos;
List<(String, double, double)> infos;

HisokiImageProvider({required this.infos, required this.id});

Expand All @@ -30,14 +29,14 @@ class HisokiImageProvider extends VioletImageProvider {

@override
Future<String> getImageUrl(int page) async {
return infos[page].item1;
return infos[page].$1;
}

@override
bool canGetImageUrlSync() => true;

@override
String? getImageUrlSync(int page) => infos[page].item1;
String? getImageUrlSync(int page) => infos[page].$1;

@override
int length() {
Expand All @@ -48,8 +47,7 @@ class HisokiImageProvider extends VioletImageProvider {

@override
Future<double> getEstimatedImageHeight(int page, double baseWidth) async {
return _estimatedCache[page] =
infos[page].item3 * baseWidth / infos[page].item2;
return _estimatedCache[page] = infos[page].$3 * baseWidth / infos[page].$2;
}

@override
Expand Down
7 changes: 3 additions & 4 deletions violet/lib/component/hitomi/comments.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import 'dart:io';

import 'package:flutter/services.dart';
import 'package:path/path.dart';
import 'package:tuple/tuple.dart';

class CommentsCount {
static List<Tuple2<int, int>>? counts;
static List<(int, int)>? counts;

static Future<void> init() async {
String data;
Expand All @@ -23,8 +22,8 @@ class CommentsCount {

Map<String, dynamic> dataCounts = json.decode(data);
counts = dataCounts.entries
.map((x) => Tuple2<int, int>(int.parse(x.key), x.value as int))
.map((x) => (int.parse(x.key), x.value as int))
.toList();
counts!.sort((x, y) => y.item2.compareTo(x.item2));
counts!.sort((x, y) => y.$2.compareTo(x.$2));
}
}
99 changes: 42 additions & 57 deletions violet/lib/component/hitomi/hitomi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'dart:io';

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tuple/tuple.dart';
import 'package:violet/algorithm/distance.dart';
import 'package:violet/component/hitomi/displayed_tag.dart';
import 'package:violet/component/hitomi/tag_translate.dart';
Expand All @@ -16,12 +15,11 @@ import 'package:violet/variables.dart';

class HitomiManager {
// [Image List], [Big Thumbnail List (Perhaps only two are valid.)], [Small Thubmnail List]
static Future<Tuple3<List<String>, List<String>, List<String>>> getImageList(
static Future<(List<String>, List<String>, List<String>)> getImageList(
String id) async {
final result = await ScriptManager.runHitomiGetImageList(int.parse(id));
if (result != null) return result;
return const Tuple3<List<String>, List<String>, List<String>>(
<String>[], <String>[], <String>[]);
return const (<String>[], <String>[], <String>[]);
}

static int? getArticleCount(String classification, String name) {
Expand Down Expand Up @@ -106,8 +104,7 @@ class HitomiManager {
}

static Map<String, dynamic>? tagmap;
static Future<List<Tuple2<DisplayedTag, int>>> queryAutoComplete(
String prefix,
static Future<List<(DisplayedTag, int)>> queryAutoComplete(String prefix,
[bool useTranslated = false]) async {
await loadIndexIfRequired();

Expand All @@ -120,73 +117,68 @@ class HitomiManager {
return _queryAutoCompleteFullSearch(prefix, useTranslated);
}

static List<Tuple2<DisplayedTag, int>> _queryAutoCompleteWithTagmap(
static List<(DisplayedTag, int)> _queryAutoCompleteWithTagmap(
String prefix, bool useTranslated) {
final groupOrig = prefix.split(':')[0];
final group = normalizeTagPrefix(groupOrig);
final name = prefix.split(':').last;

final results = <Tuple2<DisplayedTag, int>>[];
final results = <(DisplayedTag, int)>[];
if (!tagmap!.containsKey(group)) return results;

final nameCountsMap = tagmap![group] as Map<dynamic, dynamic>;
if (!useTranslated) {
results.addAll(nameCountsMap.entries
.where((e) => e.key.toString().toLowerCase().contains(name))
.map((e) => Tuple2<DisplayedTag, int>(
DisplayedTag(group: group, name: e.key), e.value)));
.map((e) => (DisplayedTag(group: group, name: e.key), e.value)));
} else {
results.addAll(TagTranslate.containsTotal(name)
.where((e) => e.group! == group && nameCountsMap.containsKey(e.name))
.map((e) => Tuple2<DisplayedTag, int>(e, nameCountsMap[e.name])));
.map((e) => (e, nameCountsMap[e.name])));
}
results.sort((a, b) => b.item2.compareTo(a.item2));
results.sort((a, b) => b.$2.compareTo(a.$2));
return results;
}

static List<Tuple2<DisplayedTag, int>> _queryAutoCompleteFullSearch(
static List<(DisplayedTag, int)> _queryAutoCompleteFullSearch(
String prefix, bool useTranslated) {
if (useTranslated) {
final results = TagTranslate.containsTotal(prefix)
.where((e) => tagmap![e.group].containsKey(e.name))
.map((e) => Tuple2<DisplayedTag, int>(e, tagmap![e.group][e.name]))
.map((e) => (e, tagmap![e.group][e.name] as int))
.toList();
results.sort((a, b) => b.item2.compareTo(a.item2));
results.sort((a, b) => b.$2.compareTo(a.$2));
return results;
}

final results = <Tuple2<DisplayedTag, int>>[];
final results = <(DisplayedTag, int)>[];

tagmap!['tag'].forEach((group, count) {
if (group.contains(':')) {
final subGroup = group.split(':');
if (subGroup[1].contains(prefix)) {
results.add(Tuple2<DisplayedTag, int>(
DisplayedTag(group: subGroup[0], name: group), count));
results.add((DisplayedTag(group: subGroup[0], name: group), count));
}
} else if (group.contains(prefix)) {
results.add(Tuple2<DisplayedTag, int>(
DisplayedTag(group: 'tag', name: group), count));
results.add((DisplayedTag(group: 'tag', name: group), count));
}
});

tagmap!.forEach((group, value) {
if (group != 'tag') {
value.forEach((name, count) {
if (name.toLowerCase().contains(prefix)) {
results.add(Tuple2<DisplayedTag, int>(
DisplayedTag(group: group, name: name), count));
results.add((DisplayedTag(group: group, name: name), count));
}
});
}
});

results.sort((a, b) => b.item2.compareTo(a.item2));
results.sort((a, b) => b.$2.compareTo(a.$2));
return results;
}

static Future<List<Tuple2<DisplayedTag, int>>> queryAutoCompleteFuzzy(
String prefix,
static Future<List<(DisplayedTag, int)>> queryAutoCompleteFuzzy(String prefix,
[bool useTranslated = false]) async {
await loadIndexIfRequired();

Expand All @@ -198,56 +190,49 @@ class HitomiManager {
final name = prefix.split(':').last;

// <Tag, Similarity, Count>
final results = <Tuple3<DisplayedTag, int, int>>[];
if (!tagmap!.containsKey(group)) return <Tuple2<DisplayedTag, int>>[];
final results = <(DisplayedTag, int, int)>[];
if (!tagmap!.containsKey(group)) return <(DisplayedTag, int)>[];

final nameCountsMap = tagmap![group];
if (!useTranslated) {
nameCountsMap.forEach((key, value) {
results.add(Tuple3<DisplayedTag, int, int>(
DisplayedTag(group: group, name: key),
Distance.levenshteinDistance(
name.runes.toList(), key.runes.toList()),
value));
results.add((
DisplayedTag(group: group, name: key),
Distance.levenshteinDistance(
name.runes.toList(), key.runes.toList()),
value
));
});
} else {
results.addAll(TagTranslate.containsFuzzingTotal(name)
.where((e) =>
e.item1.group! == group &&
nameCountsMap.containsKey(e.item1.name))
.map((e) => Tuple3<DisplayedTag, int, int>(
e.item1, e.item2, nameCountsMap[e.item1.name])));
e.$1.group! == group && nameCountsMap.containsKey(e.$1.name))
.map((e) => (e.$1, e.$2, nameCountsMap[e.$1.name])));
}
results.sort((a, b) => a.item2.compareTo(b.item2));
return results
.map((e) => Tuple2<DisplayedTag, int>(e.item1, e.item3))
.toList();
results.sort((a, b) => a.$2.compareTo(b.$2));
return results.map((e) => (e.$1, e.$3)).toList();
} else {
if (!useTranslated) {
final results = <Tuple3<DisplayedTag, int, int>>[];
final results = <(DisplayedTag, int, int)>[];
tagmap!.forEach((group, value) {
value.forEach((name, count) {
results.add(Tuple3<DisplayedTag, int, int>(
DisplayedTag(group: group, name: name),
Distance.levenshteinDistance(
prefix.runes.toList(), name.runes.toList()),
count));
results.add((
DisplayedTag(group: group, name: name),
Distance.levenshteinDistance(
prefix.runes.toList(), name.runes.toList()),
count
));
});
});
results.sort((a, b) => a.item2.compareTo(b.item2));
return results
.map((e) => Tuple2<DisplayedTag, int>(e.item1, e.item3))
.toList();
results.sort((a, b) => a.$2.compareTo(b.$2));
return results.map((e) => (e.$1, e.$3)).toList();
} else {
final results = TagTranslate.containsFuzzingTotal(prefix)
.where((e) => tagmap![e.item1.group].containsKey(e.item1.name))
.map((e) => Tuple3<DisplayedTag, int, int>(
e.item1, tagmap![e.item1.group][e.item1.name], e.item2))
.toList();
results.sort((a, b) => a.item3.compareTo(b.item3));
return results
.map((e) => Tuple2<DisplayedTag, int>(e.item1, e.item2))
.where((e) => tagmap![e.$1.group].containsKey(e.$1.name))
.map((e) => (e.$1, tagmap![e.$1.group][e.$1.name] as int, e.$2))
.toList();
results.sort((a, b) => a.$3.compareTo(b.$3));
return results.map((e) => (e.$1, e.$2)).toList();
}
}
}
Expand Down
Loading

0 comments on commit 3e09877

Please sign in to comment.