239 lines
5.7 KiB
Dart
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);
|
|
}
|