Añadida la descarga de archivos. Funciona con enlaces que nos llevan…

Añadida la descarga de archivos. Funciona con enlaces que nos llevan directamente a una imagen. El nombre de la imagen por ahora es aleatorio
parent 420968f4
import 'dart:io'; import 'dart:io';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:prueba_multimedia/modelo/conversor.dart'; import 'package:prueba_multimedia/modelo/conversor.dart';
import 'convertible.dart'; import 'convertible.dart';
...@@ -18,4 +19,9 @@ class Archivo extends Convertible { ...@@ -18,4 +19,9 @@ class Archivo extends Convertible {
{ {
metadatos = Conversor.getMetadatos(this); metadatos = Conversor.getMetadatos(this);
} }
@override
Future<ReturnCode?> convertir(String pathSalida) async {
return Conversor.convertir(this, pathSalida);
}
} }
import 'dart:io'; import 'dart:io';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/archivo.dart'; import 'package:prueba_multimedia/modelo/archivo.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
...@@ -176,4 +177,9 @@ class InfoFormato extends Convertible { ...@@ -176,4 +177,9 @@ class InfoFormato extends Convertible {
@override @override
int get hashCode => Object.hash(formatoOriginal, formatoDestino, calidadSalida, _carpeta, seleccionado, subCarpeta); int get hashCode => Object.hash(formatoOriginal, formatoDestino, calidadSalida, _carpeta, seleccionado, subCarpeta);
@override
Future<ReturnCode?> convertir(String _) {
throw UnimplementedError("Esta función no debería de llamarse nunca");
}
} }
\ No newline at end of file
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'elemento_seleccionable.dart'; import 'elemento_seleccionable.dart';
import 'formato.dart'; import 'formato.dart';
class Convertible extends ElementoSeleccionable{ abstract class Convertible extends ElementoSeleccionable{
final Formato _formatoOriginal; final Formato _formatoOriginal;
Formato? formatoDestino; Formato? formatoDestino;
Calidad? calidadSalida; Calidad? calidadSalida;
...@@ -12,7 +14,5 @@ class Convertible extends ElementoSeleccionable{ ...@@ -12,7 +14,5 @@ class Convertible extends ElementoSeleccionable{
required Formato formatoOriginal}): required Formato formatoOriginal}):
_formatoOriginal = formatoOriginal; _formatoOriginal = formatoOriginal;
void convertir(){ Future<ReturnCode?> convertir(String pathSalida);
// TODO: <implement>
}
} }
\ No newline at end of file
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'convertible.dart'; import 'package:path_provider/path_provider.dart';
import 'formato.dart'; import 'package:uuid/uuid.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
// TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO? // TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO?
class Enlace extends Convertible{ class Enlace extends Convertible {
final String _direccion; final String _url;
final RedSocial _redSocial; late final Future<File> _file;
List<String> metadatos = []; bool _descargado = false;
String get url => _url;
Future<File> get archivo async => await _file;
bool get descargado => _descargado;
Enlace({required String super.id, required String direccion}): Enlace({required String super.id, required String direccion}):
_direccion = direccion, _url = direccion, super(
_redSocial = RedSocial.FACEBOOK, nombre: "Enlace",
super(nombre: direccion.split('/').last, formatoOriginal: Formato.fromExtension('jpg')!,
// TODO: POR AHORA USAMOS (!) PERO HAY QUE TENERLO EN CUENTA icon: const Icon(Icons.link)
formatoOriginal: Formato.fromExtension('png')!, )
icon: Icon(Icons.insert_drive_file_outlined)); {
_file = _descargar(_url);
}
Future<File> _descargar(String direccion) async {
// Descargamos los datos
final dio = Dio();
final response = dio.get(_url,
options: Options(
responseType: ResponseType.bytes
)
);
// Escribimos los datos en archivo temporal
Directory temp = await getTemporaryDirectory();
final File file = await File("${temp.path}/${const Uuid().v1().toString()}.${formatoOriginal.name}").create();
final raf = file.openSync(mode: FileMode.write);
raf.writeFromSync((await response).data);
await raf.close();
_descargado = true;
return file;
}
@override @override
void convertir() { Future<ReturnCode?> convertir(String pathSalida) async {
// TODO: <implement> Descarga desde internet... // Eliminamos el archivo temporal después de la conversión
super.convertir(); Archivo archivo = Archivo(id: id, file: await _file);
archivo.formatoDestino = formatoDestino;
final result = Conversor.convertir(archivo, pathSalida);
result.then((_) async => (await _file).delete());
return result;
} }
} }
......
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/enlace.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import 'carpeta.dart'; import 'carpeta.dart';
import 'elemento_seleccionable.dart'; import 'elemento_seleccionable.dart';
...@@ -53,6 +54,15 @@ class ListaSeleccionables extends ChangeNotifier { ...@@ -53,6 +54,15 @@ class ListaSeleccionables extends ChangeNotifier {
return false; return false;
} }
bool addEnlace(String url) {
_seleccionables.add( Enlace(
id: const Uuid().v1(),
direccion: url
));
notifyListeners();
return true;
}
void reinsertar(int index, ElementoSeleccionable element){ void reinsertar(int index, ElementoSeleccionable element){
if(index > _seleccionables.length){ if(index > _seleccionables.length){
_seleccionables.add(element); _seleccionables.add(element);
......
...@@ -85,30 +85,77 @@ class ActionButton extends StatelessWidget { ...@@ -85,30 +85,77 @@ class ActionButton extends StatelessWidget {
} }
} }
// TODO: Implementar descarga de archivos /// Pide al usuario que introduzca un enlace y descarga el archivo
void enlaceAction() {} void enlaceAction() async {
String? url = await showDialog(context: context, builder: (context) {
final textEditingController = TextEditingController();
return SimpleDialog(
title: const Text("Introducir enlace"),
children: [
SimpleDialogOption(
child: Column(
children: [
SimpleDialogOption(
child: TextField(
controller: textEditingController,
),
),
const SizedBox(height: 16.0,),
SimpleDialogOption(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, textEditingController.text);
},
child: const Text("Aceptar"),
),
SimpleDialogOption(
onPressed: () { Navigator.pop(context); },
child: const Text("Cancelar"),
),
],
),
)
],
),
)
],
);
});
if (url != null) {
manager.addEnlace(url);
}
}
/// Coloca el resultado de la conversión en la carpeta de salida /// Coloca el resultado de la conversión en la carpeta de salida
void copiarAction() async { void copiarAction() async {
if(await _comprobacionesPreviasConversion(context)) { if(await _comprobacionesPreviasConversion(context)) {
// Averiguamos donde colocar los archivos de salida
String? directorioSalida = providerAjustes.carpetaSalida.isNotEmpty String? directorioSalida = providerAjustes.carpetaSalida.isNotEmpty
? providerAjustes.carpetaSalida ? providerAjustes.carpetaSalida
: await FilePicker.platform.getDirectoryPath(); : await FilePicker.platform.getDirectoryPath();
final resultados = <Future<ReturnCode?>>[];
if(directorioSalida != null){ if(directorioSalida != null){
_actualizadorProgreso(); // _actualizadorProgreso();
while(manager.seleccionables.isNotEmpty){ while(manager.seleccionables.isNotEmpty){
ElementoSeleccionable sel = manager.seleccionables.first; ElementoSeleccionable sel = manager.seleccionables.first;
if(sel is Carpeta){ if(sel is Carpeta){
for (var archivo in sel.elementosSeleccionados) {
Directory d = await Directory("$directorioSalida/${sel.nombre}").create(); Directory d = await Directory("$directorioSalida/${sel.nombre}").create();
Conversor.convertir(archivo, d.path); for (var archivo in sel.elementosSeleccionados) {
resultados.add(archivo.convertir(d.path));
} }
} }
else if (sel is Archivo){ else if (sel is Convertible){
Conversor.convertir(sel, directorioSalida); resultados.add(sel.convertir(directorioSalida));
}
if (manager.seleccionables.length == 1) {
for (final result in resultados) {
await result;
}
} }
manager.borraSeleccionable(0); manager.borraSeleccionable(0);
...@@ -118,6 +165,7 @@ class ActionButton extends StatelessWidget { ...@@ -118,6 +165,7 @@ class ActionButton extends StatelessWidget {
} }
/// Igual que copiar pero guarda el resultado en un .zip /// Igual que copiar pero guarda el resultado en un .zip
/// TODO (RAFA): CREAR LOS ARCHIVOS TEMPORALES EN OTRO SITIO
void comprimirAction() async { void comprimirAction() async {
if(await _comprobacionesPreviasConversion(context)) { if(await _comprobacionesPreviasConversion(context)) {
// Averiguamos donde colocar los archivos de salida // Averiguamos donde colocar los archivos de salida
...@@ -143,7 +191,7 @@ class ActionButton extends StatelessWidget { ...@@ -143,7 +191,7 @@ class ActionButton extends StatelessWidget {
Directory d = await Directory("$directorioSalida/${sel.nombre}").create(); Directory d = await Directory("$directorioSalida/${sel.nombre}").create();
final resultsConversion = <Future<ReturnCode?>>[]; final resultsConversion = <Future<ReturnCode?>>[];
for (var archivo in sel.elementosSeleccionados) { for (var archivo in sel.elementosSeleccionados) {
resultsConversion.add(Conversor.convertir(archivo, d.path)); resultsConversion.add(archivo.convertir(d.path));
} }
// Esperamos a la conversión y añadimos a zip // Esperamos a la conversión y añadimos a zip
...@@ -151,13 +199,13 @@ class ActionButton extends StatelessWidget { ...@@ -151,13 +199,13 @@ class ActionButton extends StatelessWidget {
await result; await result;
} }
resultsZip.add( resultsZip.add(
// Cuando se añada al zip eliminamos los archivos temporales
zipFileEncoder.addDirectory(d)..then((_) => d.delete(recursive: true)) zipFileEncoder.addDirectory(d)..then((_) => d.delete(recursive: true))
); );
} }
// Conversion de archivos // Conversion de archivos y enlaces
else if (sel is Archivo){ else if (sel is Convertible){
// Esperamos a la conversión y añadimos a zip sel.convertir(directorioSalida);
await Conversor.convertir(sel, directorioSalida);
File tempFile = await File( File tempFile = await File(
"$directorioSalida/${sel.nombre}.${sel.formatoDestino?.name}" "$directorioSalida/${sel.nombre}.${sel.formatoDestino?.name}"
).create(); ).create();
...@@ -189,6 +237,7 @@ class ActionButton extends StatelessWidget { ...@@ -189,6 +237,7 @@ class ActionButton extends StatelessWidget {
// ------------------------ UTILIDADES ------------------------ // // ------------------------ UTILIDADES ------------------------ //
/// Actualiza la barra de progreso de la conversión de forma asíncrona /// Actualiza la barra de progreso de la conversión de forma asíncrona
void _actualizadorProgreso() async { void _actualizadorProgreso() async {
manager.iniciarConversion(); manager.iniciarConversion();
......
...@@ -43,6 +43,7 @@ dependencies: ...@@ -43,6 +43,7 @@ dependencies:
ffmpeg_kit_flutter_new: ^1.6.1 ffmpeg_kit_flutter_new: ^1.6.1
shared_preferences: ^2.5.3 shared_preferences: ^2.5.3
archive: ^4.0.7 archive: ^4.0.7
dio: ^5.8.0+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment