import 'dart:core'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:funkblubber/funkentity.dart'; import 'package:funkblubber/console.dart' as console; import 'package:funkblubber/string_utils.dart' as utils; Future download({ required final FunkObject object, required final String path, }) async { bool success = false; console.info('Downloading'); switch (object.kind) { case FunkEntity.album: success = await _downloadAlbum(object, path); break; case FunkEntity.artist: success = await _downloadArtist(object, path); break; case FunkEntity.track: success = await _downloadTrack(object, path); break; default: console.info(' nothing...'); break; } return success; } Future _downloadArtist( final FunkObject object, final String path, ) async { Response response = await Dio().get( 'https://${object.domain}/api/v1/artists/${object.id}/?' 'refresh=false', ); final String pathAppend = utils.sanitizePath(response.data['name']); bool folderCreated = true; try { await Directory('$path/$pathAppend').create(); } catch (e) { console.error(e.toString()); folderCreated = false; } if (!folderCreated) { return false; } console.info('Artist: $pathAppend'); response = await Dio().get( 'https://${object.domain}/api/v1/albums/?' 'artist=${object.id}&ordering=creation_date&' 'page=1&page_size=16&scope=all', ); final List> results = []; for (final albumResponse in response.data['results']) { final result = _downloadAlbum( FunkObject( domain: object.domain, id: albumResponse['id'].toString(), kind: FunkEntity.album, ), '$path/$pathAppend', ); results.add(result); } final List successes = await Future.wait(results); return successes.every((final success) => success); } Future _downloadAlbum( final FunkObject object, final String path, ) async { final response = await Dio().get( 'https://${object.domain}/api/v1/tracks/?' 'album=${object.id}&ordering=creation_date&' 'page=1&page_size=16&scope=all', ); final String pathAppend = utils.sanitizePath( response.data['results'][0]['album']['title'], ); bool folderCreated = true; try { await Directory('$path/$pathAppend').create(); } catch (e) { console.error(e.toString()); folderCreated = false; } if (!folderCreated) { return false; } console.info('Album: $pathAppend'); final List> results = []; for (final songResponse in response.data['results']) { final String songTitle = utils.sanitizePath(songResponse['title']); final String ext = songResponse['uploads'][0]['extension']; final result = _downloadTrackObject( FunkObject( domain: object.domain, id: songResponse['listen_url'], kind: FunkEntity.track, ), '$path/$pathAppend/$songTitle.$ext', ); results.add(result); } final List successes = await Future.wait(results); return successes.every((final success) => success); } Future _downloadTrack( final FunkObject object, final String path, ) async { final response = await Dio().get( 'https://${object.domain}/api/v1/tracks/${object.id}/?refresh=false', ); final String songTitle = utils.sanitizePath(response.data['title']); final String ext = response.data['uploads'][0]['extension']; return _downloadTrackObject( FunkObject( domain: object.domain, id: response.data['uploads'][0]['listen_url'], kind: FunkEntity.track, ), '$path/$songTitle.$ext', ); } Future _downloadTrackObject( final FunkObject object, final String path, ) async { bool success = true; try { final Response response = await Dio().get( 'https://${object.domain}${object.id}', options: Options( responseType: ResponseType.bytes, followRedirects: false, ), ); console.info('- $path'); final File file = File(path); final accessFile = file.openSync(mode: FileMode.write); accessFile.writeFromSync(response.data); await accessFile.close(); } catch (e) { console.error(e.toString()); success = false; } return success; }