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 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:prueba_multimedia/modelo/conversor.dart';
import 'convertible.dart';
......@@ -18,4 +19,9 @@ class Archivo extends Convertible {
{
metadatos = Conversor.getMetadatos(this);
}
@override
Future<ReturnCode?> convertir(String pathSalida) async {
return Conversor.convertir(this, pathSalida);
}
}
import 'dart:io';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/archivo.dart';
import 'package:uuid/uuid.dart';
......@@ -176,4 +177,9 @@ class InfoFormato extends Convertible {
@override
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 'formato.dart';
class Convertible extends ElementoSeleccionable{
abstract class Convertible extends ElementoSeleccionable{
final Formato _formatoOriginal;
Formato? formatoDestino;
Calidad? calidadSalida;
......@@ -12,7 +14,5 @@ class Convertible extends ElementoSeleccionable{
required Formato formatoOriginal}):
_formatoOriginal = formatoOriginal;
void convertir(){
// TODO: <implement>
}
Future<ReturnCode?> convertir(String pathSalida);
}
\ 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 'convertible.dart';
import 'formato.dart';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
// TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO?
class Enlace extends Convertible{
final String _direccion;
final RedSocial _redSocial;
List<String> metadatos = [];
class Enlace extends Convertible {
final String _url;
late final Future<File> _file;
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}):
_direccion = direccion,
_redSocial = RedSocial.FACEBOOK,
super(nombre: direccion.split('/').last,
// TODO: POR AHORA USAMOS (!) PERO HAY QUE TENERLO EN CUENTA
formatoOriginal: Formato.fromExtension('png')!,
icon: Icon(Icons.insert_drive_file_outlined));
_url = direccion, super(
nombre: "Enlace",
formatoOriginal: Formato.fromExtension('jpg')!,
icon: const Icon(Icons.link)
)
{
_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
void convertir() {
// TODO: <implement> Descarga desde internet...
super.convertir();
Future<ReturnCode?> convertir(String pathSalida) async {
// Eliminamos el archivo temporal después de la conversión
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 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/enlace.dart';
import 'package:uuid/uuid.dart';
import 'carpeta.dart';
import 'elemento_seleccionable.dart';
......@@ -53,6 +54,15 @@ class ListaSeleccionables extends ChangeNotifier {
return false;
}
bool addEnlace(String url) {
_seleccionables.add( Enlace(
id: const Uuid().v1(),
direccion: url
));
notifyListeners();
return true;
}
void reinsertar(int index, ElementoSeleccionable element){
if(index > _seleccionables.length){
_seleccionables.add(element);
......
......@@ -85,30 +85,77 @@ class ActionButton extends StatelessWidget {
}
}
// TODO: Implementar descarga de archivos
void enlaceAction() {}
/// Pide al usuario que introduzca un enlace y descarga el archivo
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
void copiarAction() async {
if(await _comprobacionesPreviasConversion(context)) {
// Averiguamos donde colocar los archivos de salida
String? directorioSalida = providerAjustes.carpetaSalida.isNotEmpty
? providerAjustes.carpetaSalida
: await FilePicker.platform.getDirectoryPath();
final resultados = <Future<ReturnCode?>>[];
if(directorioSalida != null){
_actualizadorProgreso();
// _actualizadorProgreso();
while(manager.seleccionables.isNotEmpty){
ElementoSeleccionable sel = manager.seleccionables.first;
if(sel is Carpeta){
Directory d = await Directory("$directorioSalida/${sel.nombre}").create();
for (var archivo in sel.elementosSeleccionados) {
Directory d = await Directory("$directorioSalida/${sel.nombre}").create();
Conversor.convertir(archivo, d.path);
resultados.add(archivo.convertir(d.path));
}
}
else if (sel is Archivo){
Conversor.convertir(sel, directorioSalida);
else if (sel is Convertible){
resultados.add(sel.convertir(directorioSalida));
}
if (manager.seleccionables.length == 1) {
for (final result in resultados) {
await result;
}
}
manager.borraSeleccionable(0);
......@@ -118,6 +165,7 @@ class ActionButton extends StatelessWidget {
}
/// Igual que copiar pero guarda el resultado en un .zip
/// TODO (RAFA): CREAR LOS ARCHIVOS TEMPORALES EN OTRO SITIO
void comprimirAction() async {
if(await _comprobacionesPreviasConversion(context)) {
// Averiguamos donde colocar los archivos de salida
......@@ -143,7 +191,7 @@ class ActionButton extends StatelessWidget {
Directory d = await Directory("$directorioSalida/${sel.nombre}").create();
final resultsConversion = <Future<ReturnCode?>>[];
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
......@@ -151,13 +199,13 @@ class ActionButton extends StatelessWidget {
await result;
}
resultsZip.add(
zipFileEncoder.addDirectory(d)..then((_) => d.delete(recursive: true))
// Cuando se añada al zip eliminamos los archivos temporales
zipFileEncoder.addDirectory(d)..then((_) => d.delete(recursive: true))
);
}
// Conversion de archivos
else if (sel is Archivo){
// Esperamos a la conversión y añadimos a zip
await Conversor.convertir(sel, directorioSalida);
// Conversion de archivos y enlaces
else if (sel is Convertible){
sel.convertir(directorioSalida);
File tempFile = await File(
"$directorioSalida/${sel.nombre}.${sel.formatoDestino?.name}"
).create();
......@@ -188,6 +236,7 @@ class ActionButton extends StatelessWidget {
// ------------------------ UTILIDADES ------------------------ //
/// Actualiza la barra de progreso de la conversión de forma asíncrona
void _actualizadorProgreso() async {
......
......@@ -43,6 +43,7 @@ dependencies:
ffmpeg_kit_flutter_new: ^1.6.1
shared_preferences: ^2.5.3
archive: ^4.0.7
dio: ^5.8.0+1
dev_dependencies:
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