-
Notifications
You must be signed in to change notification settings - Fork 1
iRec orphans
Como sabemos, cada vez que iniciamos una entrevista **pre-**generamos el archivo de audio. Esto lo hacemos porque necesitamos tenerlo listo o simplemente porque no somos mas listos como para hacerlo de otra forma. Como sea, la situacion es que quedan archivos, que si bien no ocupan nada, es basura que queda por ahi y deberiamos limpiarla.
Para poder determinar que archivos debemos eliminar vamos a:
- obtener una lista de archivos en la carpeta de audio
- obtener una lista de paths que estan almacenados en las entrevistas que tenemos guardadas en
entrevistas.lista
- cruzaremos un listado con el otro y, todos aquellos archivos que no existan en el listado extraido de las entrevistas, deberian ser eliminados
Para esto vamos a agregar metodos en entrevistas
y en fileApi
.
La ultima version que tenemos de fileApi
tiene estos metodos:
var fileApi = {
ready: false, // <--solo por las dudas
initialize: function(callback){
var path = cordova.file.externalDataDirectory;
//si no hay problemas, llamamos a callback con el primer
//parametro en null (lo que seria el error)
var onResolve = function(directoryEntry) {
fileApi.dir = directoryEntry;
fileApi.ready = true;
callback && callback(null, fileApi);
}
//si hay un error llamamos a callback con el error
//como primer parametro (ver arriba)
var onError = function(err){
callback && callback(err, fileApi);
}
window.resolveLocalFileSystemURL(path, onResolve, onError);
},
writeTextFile: function(file, content, callback) {
var onFile = function(fileEntry) {
fileEntry.createWriter(
function(fileWriter){
fileWriter.write(content);
callback && callback(content);
}, fileApi.onError);
}
fileApi.dir.getFile(file, {create: true}, onFile, fileApi.onError);
},
onError: function(err) {
console.log(err);
},
getDir: function(dir, callback) {
var onDir = function(dir){
callback && callback(null, dir);
}
var onError = function(err) {
callback && callback(err, null);
}
fileApi.dir.getDirectory(dir, {create:true}, onDir, onError);
}
}
fileApi
es nuestra interfaz con el sistema de archivos. La idea es que se encargue de la parte pesada y nos devuelva resultados, asi que parece un buen lugar para implementar un metodo que lea el contenido de un directorio y nos arroje el resultado.
En la documentacion del file plugin de phonegap vemos un listado de objetos y clases que el plugin puede manejar para devolvernos funcionalidad. Entre ellos figuran 3 que vamos a necesitar:
-
DirectoryEntry
- en particular el metodo
createReader
que, segun documentacion, createReader: Create a new DirectoryReader that can read entries from a directory
- en particular el metodo
-
DirectoryReader
- cuyo unico metodo es
readEntries
cuya descripcion es readEntries: Read the entries in a directory
- cuyo unico metodo es
-
FileEntry
- en la documentacion figura el metodo
remove()
...
- en la documentacion figura el metodo
Entonces, crearemos en fileApi
el metodo readDir
. Este metodo tomara como argumentos:
- dir - {String}: el nombre del directorio cuyo contenido queremos listar
- callback - {Function}: un callback para devolver el resultado
Agreguemos el metodo justo debajo del metodo getDir
ya que va a estar intimamente relacionado:
getDir: function(dir, callback) {
var onDir = function(dir){
callback && callback(null, dir);
}
var onError = function(err) {
callback && callback(err, null);
}
fileApi.dir.getDirectory(dir, {create:true}, onDir, onError);
}, // <-- no se olviden esta coma
readDir: function(directoryEntry, callback) {
directoryEntry.createReader().readEntries(callback);
},
Por que estan relacionados los 2 metodos? Porque el metodo createReader
es de un DirectoryEntry, es decir, no podemos pasarle un String con el nombre del archivo, necesitamos pasarle el objeto que nos devuelve getDir
. Si se fijan, getDir
si puede recibir el nombre del directorio que queremos como un {String}. Entonces, la llamada para obtener el contenido de un directorio sera algo asi (recordando que son todas funciones asincronicas):
fileApi.getDir('audio', function(directoryEntry) {
directoryEntry.readEntries(function(entries){
// aca finalmente tenemos entries, que
// es un array con FileEntries
});
});
Con este metodo implementado ya podemos cerrar fileApi
y empezar a agregar metodos en entrevistas
En el objeto entrevistas
agregaremos el metodo obtenerListaDeArchivosDeAudio
al final del objeto (antes del ultimo cierre de llave, separado con una coma):
obtenerListaDeArchivosDeAudio: function(callback) {
fileApi.getDir('audio', function(err, dirEntry){
if(err){
callback && callback(err, []);
}
fileApi.readDir(dirEntry, function(entries){
callback && callback(null, entries);
});
});
},
Este metodo tambien lo haremos asincronico, que llamara el callback que le proveamos con:
- err - {Error}: un error, si lo hubiese
- entries - {Array}: un array de FileEntries, resultado del
fileApi.readDir()
Tambien necesitamos el listado de entrevistas, pero necesitamos un listado mas simple, uno que solo contenga el path de los archivos de audio de las entrevistas, entonces generaremos el metodo obtenerArchivosDeAudioDeEntrevistas()
, que tambien sera asincronico. La magia de este metodo sera levantar todo el listado en entrevistas.lista
e iterarlo para extraer un array simple con los paths a los archivos de audio:
obtenerArchivosDeAudioDeEntrevistas: function(callback) {
var filePaths = [];
$.each(entrevistas.lista, function(idx, item){
filePaths.push(item.audioPath);
});
callback(filePaths);
},
Y por ultimo, un metodo que llame a los dos metodos anteriores, encadenado uno con otro, y luego itere por sobre cada archivo de audio y conforme un nuevo listado con aquellos que no figuren entre los archivos de audio de las entrevistas y lo devuelva, tambien de manera asincronica.
Para cruzar los 2 arrays usaremos el metodo Array.indexOf
, que nos devuelve un entero representando el indice del array donde se encontro el valor que estamos buscando. Si no se encuentra devolvera -1
Agreguen el metodo encontrarArchivosHuerfanos()
:
encontrarArchivosHuerfanos: function(callback) {
var huerfanos = [];
entrevistas.obtenerArchivosDeAudioDeEntrevistas(function(paths){
entrevistas.obtenerListaDeArchivosDeAudio(function(err, files){
if(err) {
//si hay error devuelvo el array vacio
return callback && callback(huerfanos);
}
$.each(files, function(i,e){
// por cada archivo en el directorio
// buscamos el nativeURL en el array
// de paths que obtuvimos de las entrevistas
if(paths.indexOf(e.nativeURL) == -1) {
// si NO se encuentra
// es un archivo huerfano
huerfanos.push(e);
}
});
callback && callback(huerfanos);
});
});
},
Como bien nombramos el metodo encontrarArchivosHuerfanos
la idea es que solo los busque y los devuelva, no que los borre. Lo que hagamos con ellos sera parte de la funcionalidad donde lo querramos usar.
Podriamos hacerlo al arrancar la aplicacion, o silenciosamente al salir de una entrevista. Pero por el momento vamos a crear un boton con la funcion especifica de buscarlos y borrarlos.
Crearemos el boton en la pagina #home
, debajo del boton para entrevistar, en el archivo index.html
y le pondremos el id
limpiarHuerfanos:
<div data-role="content">
<a href="#entrevista-list" class="ui-btn">Archivo de entrevistas</a>
<a href="#guia-list" class="ui-btn">Entrevistar</a>
<a href="#" id="limpiarHuerfanos" class="ui-btn">Borrar archivos temporales</a>
</div>
Luego, en el archivo js/index.js
agregaremos un handler para el evento pagecreate
de la pagina #home
(hasta el momento no existia dado que no inicializabamos nada en #home
):
$('#home').on('pagecreate', function(){
$('#limpiarHuerfanos').on('click', function(evt){
// cancelamos el comportamiento del boton
evt.preventDefault();
// mostramos el spinner, por si demora mucho
$.mobile.loading('show');
// y llamamos a nuestro metodo en entrevistas
entrevistas.encontrarArchivosHuerfanos(function(archivos){
// contamos cuantos volvieron
var cantidad = archivos.length;
// luego iteramos por el resultado
$.each(archivos, function(i,e){
// y como sabemos que son FileEntries
// ejecutamos .remove() en cada uno
e.remove();
});
// mostramos un mensaje y escondemos el spinner
alert('Se eliminaron '+cantidad+' archivos huerfanos');
$.mobile.loading('hide');
});
});
});
- Repaso y conceptos basicos
- Ejercicios para repasar
- Problematica de desarrollo mobile
- Phonegap
- Requerimientos e instalacion
- Phonegap CLI
- [Primeros ejercicios con Phonegap](Ejercicio Phonegap)
- Plugins
- Hello world
- Estructura de un proyecto Phonegap
- Plugin Device
- Debugging
- Incorporando un framework CSS
- Plugin Vibration
- Sumando partes
- Plugin Battery Status
- Un poco de jQuery
- jQuery Mobile
- Navegacion
- Plugin Dashboard
- Revision de Plugin Dashboard
- Paginas extra
- ToDo
- Persistencia
- ToDo Persistente
- Plugin Camera
- Opciones de camara
- App Mi Galeria
- Revision de Galeria
- Plugin File
- Escribir y leer texto
- Escribir archivos binarios
- Guardando fotos
- Debugger: weinre
- Inspeccionar con weinre
- Phonegap Developer App
- Refactor de apps
- Plugin Media
- Pruebas con audio
- Control y monitoreo de audio
- Encapsular play/pausa
- Hacks
- Formato de tiempos
- Grabar y reproducir
- Proyecto Integrador
- Revision de interfaz
- Interfaz basica
- Entrevista: modelo
- Funcionalidad: revision
- Seleccion de framework
- iRec: navegacion
- iRec: fileApi
- iRec: guias
- iRec: entrevistas
- iRec: recordApi
- iRec: helpers
- iRec: mediaApi
- iRec: inicializar paginas
- iRec: refactor
- iRec: mediaApi refactor
- iRec: recordApi refactor
- iRec: helpers
- iRec: guias.js
- iRec: entrevistas.js
- iRec: crear guias
- iRec: re-inicializando
- iRec: re-ordenando
- iRec: pendientes
- iRec: reporte ux
- iRec:revision: volver
- iRec:entrevista: volver
- iRec:revision: cambios
- iRec:revision: stop
- iRec:revision: Rew 10"
- iRec:revision: tag Go
- iRec: limpieza
- Firma de apps
- Android
- Generacion de key
- Firma de apk
- Alineacion de zip
- Firmar con Phonegap
- iOS
- Detalles finales
- Config.xml
- Iconos
- Splash