You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
5.7 KiB
Dart

import 'package:funkblubber/funkentity.dart';
import 'package:funkblubber/console.dart' as console;
import 'package:funkblubber/parsing/parsing_stage.dart';
enum Action {
download,
upload,
}
class StageResult {
StageResult({required this.result, required this.stage});
final ParseResult result;
final ParsingStage stage;
}
class ParseResult {
ParseResult({
required this.success,
required this.action,
this.object,
this.localPath,
});
final FunkObject? object;
final String? localPath;
final Action action;
final bool success;
}
ParseResult extract(final List<String> args) {
ParseResult result = ParseResult(
success: false,
action: Action.download,
);
if (args.isEmpty) {
console.error('no arguments provided');
return result;
}
ParsingStage currentStage = ParsingStage.nothing;
for (final String arg in args) {
switch (currentStage) {
case ParsingStage.nothing:
final stageResult = _onNothingStage(arg, result, currentStage);
currentStage = stageResult.stage;
result = stageResult.result;
break;
case ParsingStage.album:
final stageResult = _onEntityStage(
arg,
result,
currentStage,
FunkEntity.album,
);
currentStage = stageResult.stage;
result = stageResult.result;
break;
case ParsingStage.artist:
final stageResult = _onEntityStage(
arg,
result,
currentStage,
FunkEntity.artist,
);
currentStage = stageResult.stage;
result = stageResult.result;
break;
case ParsingStage.domain:
final stageResult = _onDomainStage(arg, result, currentStage);
currentStage = stageResult.stage;
result = stageResult.result;
break;
case ParsingStage.path:
final stageResult = _onPathStage(arg, result, currentStage);
currentStage = stageResult.stage;
result = stageResult.result;
break;
default:
console.error('not implemented yet');
break;
}
}
return result;
}
StageResult _onEntityStage(
final String arg,
final ParseResult previousResult,
final ParsingStage previousStage,
final FunkEntity kind,
) {
ParsingStage currentStage = previousStage;
ParseResult result = previousResult;
if (int.tryParse(arg) != null) {
currentStage = ParsingStage.nothing;
result = ParseResult(
action: previousResult.action,
success: true,
object: FunkObject(
domain: previousResult.object?.domain ?? '',
id: arg,
kind: kind,
),
);
}
return StageResult(result: result, stage: currentStage);
}
StageResult _onDomainStage(
final String arg,
final ParseResult previousResult,
final ParsingStage previousStage,
) {
ParsingStage currentStage = previousStage;
ParseResult result = previousResult;
try {
final Uri uri = Uri.parse(arg);
currentStage = ParsingStage.nothing;
result = ParseResult(
action: previousResult.action,
success: true,
object: FunkObject(
domain: uri.toString(),
id: previousResult.object?.id ?? '',
kind: previousResult.object?.kind ?? FunkEntity.album,
),
);
} catch (e) {
console.error(e.toString());
}
return StageResult(result: result, stage: currentStage);
}
String _cutTrailingDash(final String path) =>
path.endsWith('/') ? path.substring(0, path.length - 1) : path;
StageResult _onPathStage(
final String arg,
final ParseResult previousResult,
final ParsingStage previousStage,
) {
ParsingStage currentStage = previousStage;
ParseResult result = previousResult;
currentStage = ParsingStage.nothing;
result = ParseResult(
localPath: _cutTrailingDash(arg),
action: previousResult.action,
success: true,
object: previousResult.object,
);
return StageResult(result: result, stage: currentStage);
}
StageResult _onNothingStage(
final String arg,
final ParseResult previousResult,
final ParsingStage previousStage,
) {
ParsingStage currentStage = previousStage;
ParseResult result = previousResult;
switch (arg) {
case '-A':
case '--artist':
currentStage = ParsingStage.artist;
break;
case '-a':
case '--album':
currentStage = ParsingStage.album;
break;
case '-u':
case '--upload':
currentStage = ParsingStage.upload;
break;
case '-p':
case '--path':
currentStage = ParsingStage.path;
break;
case '-d':
case '--domain':
currentStage = ParsingStage.domain;
break;
default:
try {
final Uri uri = Uri.parse(arg);
final segments = uri.pathSegments;
for (int i = 0; i < segments.length; ++i) {
switch (segments[i]) {
case 'artists':
result = ParseResult(
action: Action.download,
success: true,
object: FunkObject(
kind: FunkEntity.artist,
id: segments[i + 1],
domain: uri.host,
),
);
++i;
break;
case 'albums':
result = ParseResult(
action: Action.download,
success: true,
object: FunkObject(
kind: FunkEntity.album,
id: segments[i + 1],
domain: uri.host,
),
);
++i;
break;
}
}
} catch (e) {
console.error(e.toString());
currentStage = ParsingStage.nothing;
}
break;
}
return StageResult(result: result, stage: currentStage);
}