Skip to content

Commit

Permalink
fix: splitting artists/genres with blacklist
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Jun 9, 2024
1 parent 4dacb21 commit f8d208c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 40 deletions.
65 changes: 58 additions & 7 deletions lib/class/split_config.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:namida/controller/settings_controller.dart';
import 'package:namida/core/extensions.dart';

class ArtistsSplitConfig extends _SplitterConfig {
class ArtistsSplitConfig extends SplitterConfig {
final bool addFeatArtist;

const ArtistsSplitConfig({
ArtistsSplitConfig({
required this.addFeatArtist,
required super.separators,
required super.separatorsBlacklist,
Expand Down Expand Up @@ -38,8 +39,8 @@ class ArtistsSplitConfig extends _SplitterConfig {
}
}

class GenresSplitConfig extends _SplitterConfig {
const GenresSplitConfig({
class GenresSplitConfig extends SplitterConfig {
GenresSplitConfig({
required super.separators,
required super.separatorsBlacklist,
});
Expand Down Expand Up @@ -69,12 +70,62 @@ class GenresSplitConfig extends _SplitterConfig {
}
}

interface class _SplitterConfig {
class SplitDelimiter {
final RegExp? _regex;
const SplitDelimiter._(this._regex);

factory SplitDelimiter.fromSingle(String singleDelimiter) {
assert(singleDelimiter.length == 1);
final regex = RegExp(RegExp.escape(singleDelimiter), caseSensitive: false);
return SplitDelimiter._(regex);
}

factory SplitDelimiter.fromList(Iterable<String> delimiters) {
if (delimiters.isEmpty) return const SplitDelimiter._(null);
final regexString = delimiters.map(RegExp.escape).join('|');
final regex = RegExp(regexString, caseSensitive: false);
return SplitDelimiter._(regex);
}

List<String> multiSplit(String text, List<String> blacklist) {
if (_regex == null) return [text];

final listToAddLater = <String>[];
String filteredString = '';
if (blacklist.isNotEmpty) {
blacklist.loop((b) {
final withoutBL = text.split(b);
withoutBL.loop((s) => filteredString += s.trim());
if (withoutBL.length > 1) listToAddLater.add(b);
});
} else {
filteredString = text;
}

final splitted = filteredString.split(_regex).map((e) => e.trim()).where((e) => e.isNotEmpty).toList();
splitted.addAll(listToAddLater);
if (splitted.length > 1) splitted.sortBy((e) => text.indexOf(e));
return splitted;
}
}

interface class SplitterConfig {
final List<String> separators;
final List<String> separatorsBlacklist;
late final SplitDelimiter delimiter;

const _SplitterConfig({
SplitterConfig({
required this.separators,
required this.separatorsBlacklist,
});
}) {
delimiter = SplitDelimiter.fromList(separators);
}

List<String> splitText(String? string, {required String fallback}) {
if (string == null) return [fallback];
final config = this;
final splitted = config.delimiter.multiSplit(string.trimAll(), config.separatorsBlacklist);
if (splitted.isEmpty) return [fallback];
return splitted;
}
}
43 changes: 11 additions & 32 deletions lib/controller/indexer_controller.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// ignore_for_file: depend_on_referenced_packages

import 'dart:async';
import 'dart:io';

Expand Down Expand Up @@ -956,7 +954,7 @@ class Indexer {
final map = <Track, TrackStats>{};
final list = File(path).readAsJsonSync() as List?;
if (list != null) {
for (int i = 0; i <= list.length - 1; i++) {
for (int i = 0; i < list.length; i++) {
try {
final item = list[i];
final trst = TrackStats.fromJson(item);
Expand All @@ -975,7 +973,7 @@ class Indexer {
final allTracks = <Track>[];
final list = File(config.path).readAsJsonSync() as List?;
if (list != null) {
for (int i = 0; i <= list.length - 1; i++) {
for (int i = 0; i < list.length; i++) {
try {
final item = list[i];
final trExt = TrackExtended.fromJson(
Expand All @@ -995,15 +993,6 @@ class Indexer {
return (map, idsMap, allTracks);
}

static List<String> splitBySeparators(String? string, Iterable<String> separators, String fallback, Iterable<String> blacklist) {
final List<String> finalStrings = <String>[];
final List<String> pre = string?.trimAll().multiSplit(separators, blacklist) ?? [fallback];
pre.loop((e) {
if (e != '') finalStrings.add(e.trimAll());
});
return finalStrings;
}

/// [addArtistsFromTitle] extracts feat artists.
/// Defaults to [settings.extractFeatArtistFromTitle]
static List<String> splitArtist({
Expand All @@ -1013,25 +1002,15 @@ class Indexer {
}) {
final allArtists = <String>[];

final artistsOrg = splitBySeparators(
originalArtist,
config.separators,
UnknownTags.ARTIST,
config.separatorsBlacklist,
);
final artistsOrg = config.splitText(originalArtist, fallback: UnknownTags.ARTIST);
allArtists.addAll(artistsOrg);

if (config.addFeatArtist) {
final List<String>? moreArtists = title?.split(RegExp(r'\(ft\. |\[ft\. |\(feat\. |\[feat\. \]', caseSensitive: false));
if (moreArtists != null && moreArtists.length > 1) {
final extractedFeatArtists = moreArtists[1].split(RegExp(r'\)|\]')).first;
allArtists.addAll(
splitBySeparators(
extractedFeatArtists,
config.separators,
'',
config.separatorsBlacklist,
),
config.splitText(extractedFeatArtists, fallback: ''),
);
}
}
Expand All @@ -1042,11 +1021,9 @@ class Indexer {
String? originalGenre, {
required GenresSplitConfig config,
}) {
return splitBySeparators(
return config.splitText(
originalGenre,
config.separators,
UnknownTags.GENRE,
config.separatorsBlacklist,
fallback: UnknownTags.GENRE,
);
}

Expand Down Expand Up @@ -1173,6 +1150,8 @@ class Indexer {
allMusic.retainWhere((element) =>
settings.directoriesToExclude.value.every((dir) => !element.data.startsWith(dir)) /* && settings.directoriesToScan.any((dir) => element.data.startsWith(dir)) */);
final tracks = <(TrackExtended, int)>[];
final artistsSplitConfig = ArtistsSplitConfig.settings();
final genresSplitConfig = GenresSplitConfig.settings();
allMusic.loop((e) {
final map = e.getMap;
final artist = e.artist;
Expand All @@ -1181,21 +1160,21 @@ class Indexer {
: Indexer.splitArtist(
title: e.title,
originalArtist: artist,
config: ArtistsSplitConfig.settings(),
config: artistsSplitConfig,
);
final genre = e.genre;
final genres = genre == null
? <String>[]
: Indexer.splitGenre(
genre,
config: GenresSplitConfig.settings(),
config: genresSplitConfig,
);
final mood = map['mood'];
final moods = mood == null
? <String>[]
: Indexer.splitGenre(
mood,
config: GenresSplitConfig.settings(),
config: genresSplitConfig,
);
final bitrate = map['bitrate'] as int?;
final disc = map['disc_number'] as int?;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: namida
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
publish_to: "none"
version: 2.7.0-beta+240607208
version: 2.7.1-beta+240609197

environment:
sdk: ">=3.4.0 <4.0.0"
Expand Down

0 comments on commit f8d208c

Please sign in to comment.