def validarArchivos(): ## Función invocada mediante AJAX cuando se presiona el botón de "validar_archivos" ## en la forma, y se encontró un valor t para los campos: "es_audible_ultrasonico" ## y grabadora_id" (debido a este último, deben haberse seleccionado valores ## de "conglomerado_muestra_id" y "sitio_muestra_id"). Esta función valida: ## 1. Que el registro de los archivos no se haya realizado con anterioridad. ## 2. Que la carpeta nombre_cgl_aaaa-mm-dd/t exista. ## 3. Que dicha carpeta no esté vacía ## Regresa un JSON con: ## 1. El mensaje apropiado en cada caso, para que la vista ## lo alerte ## 2. Una bandera que indica si la validación fue exitosa o no ## 3. El "nombre" y la "fecha_visita" del conglomerado cuyo id fue recibido ## mediante AJAX, para no tener que recalcularlos en index2(). # Bandera que indica si los archivos fueron validados correctamente flag = 0 grabadoraElegidaID = request.vars.grabadora_id tipoArchivo = request.vars.es_audible_ultrasonico # Obteniendo los archivos correspondientes a la grabadora y tipo seleccionados. # ésto código no puede tronar porque, gracias a la validación en la vista, # los valores de "grabadoraElegidaID" y "tipoArchivo" son no vacíos. if tipoArchivo == "audible": archivosGrabadora = db( (db.Archivo_grabadora.grabadora_id == grabadoraElegidaID) &\ (db.Archivo_grabadora.es_audible == True) ).select() else: archivosGrabadora = db( (db.Archivo_grabadora.grabadora_id == grabadoraElegidaID) &\ (db.Archivo_grabadora.es_audible == False) ).select() datosConglomeradoNombre = "" datosConglomeradoFechaVisita = "" # Generando los distintos mensajes: if len(archivosGrabadora) > 0: mensaje = "Ya se han enviado los archivos " + tipoArchivo + "s para el " +\ "conglomerado seleccionado. Si lo necesita, borre el registro de la grabadora " +\ "en la sección de 'Revisar registros', y vuelva a declararla" else: # Obteniendo los datos del conglomerado seleccionado, con el fin de crear # el path hacia la carpeta apropiada: conglomeradoElegidoID = request.vars.conglomerado_muestra_id # Obteniendo la información del conglomerado datosConglomeradoAux = db( db.Conglomerado_muestra.id == conglomeradoElegidoID).select( db.Conglomerado_muestra.nombre, db.Conglomerado_muestra.fecha_visita) datosConglomerado = datosConglomeradoAux.first() datosConglomeradoNombre = str(datosConglomerado['nombre']) datosConglomeradoFechaVisita = str(datosConglomerado['fecha_visita']) # Creando la ruta hacia la carpeta nombre_cgl_aaaa-mm-dd/t rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( datosConglomeradoNombre, datosConglomeradoFechaVisita ) if tipoArchivo == "audible": subcarpeta = "g_a" else: subcarpeta = "g_u" rutaT = os.path.join(rutaCarpetaCglMuestra, subcarpeta) #rutaTMensaje es la rutaT expresada para que el usuario la entienda rutaTMensaje = os.path.join( 'conglomerados', datosConglomeradoNombre + '_' + datosConglomeradoFechaVisita, subcarpeta) # Verificando que dicha carpeta exista if not os.path.isdir(rutaT): mensaje = "No se encontró la carpeta " + rutaTMensaje +\ ". Favor de crearla." else: # Verificando que dicha carpeta contenga archivos wav: # Enlistando los archivos en rutaT lista_archivos = os.listdir(rutaT) # Obteniendo de éstos, cuáles son los archivos con terminación wav. lista_wav = [archivo\ for archivo in lista_archivos\ if re.search(r'wav$', archivo, re.I)] if len(lista_wav) == 0: mensaje = "La carpeta " + rutaTMensaje + " no contiene archivos " +\ "WAV, favor de agregarle los archivos " + tipoArchivo + "s" else: mensaje = "Validación exitosa para " + str(len(lista_wav)) +\ " archivos WAV declarados como " + tipoArchivo + "s en: " +\ rutaTMensaje + ". Ahora puede enviar la información." flag = 1 # Enviando el diccionario como JSON para que JS lo pueda interpretar return json.dumps(dict( flag = flag, mensaje = mensaje, conglomerado_muestra_nombre = datosConglomeradoNombre, conglomerado_muestra_fecha_visita = datosConglomeradoFechaVisita, ))
def asignarInformacionArchivo(): ## Ésta funcion se invoca mediante AJAX, y genera una forma para ## ingresar/modificar la información de la fotografía que seleccionó el ## usuario en el menú desplegable. El AJAX se activa al seleccionar un ## archivo de la lista desplegable. # Obteniendo la información del archivo que seleccionó el usuario: archivoElegidoID = request.vars.archivo_camara_id # Obteniendo la información del archivo datosArchivoAux = db(db.Archivo_camara.id == archivoElegidoID).select() datosArchivo = datosArchivoAux.first() # Creando la pantalla de revisión de archivos, considerando el caso en el # que datosArchivo esté vacía: if len(datosArchivoAux) == 0: revisionHTML = "<form id='forma_shadow'></form>" else: #HTML generado: # <form id='forma_shadow'> # <input type='hidden' name='id_archivo' value='str(datosArchivo.id)'/> # <center> # <img src='data:image/jpeg;base64,imagen_codificada' # alt='Error al cargar la fotografía' style='width:800px;height:600px;'/> # </center> # <hr/> # <div style='float:left;padding-right:60px;'> # <label for='con_fauna_evidente' style='float:left;padding-right:20px;'> # Con fauna evidente # </label> # <input type='radio' name='fauna_evidente' value='encontrada' # id='con_fauna_evidente' checked='true'/>" # </div> # <div style='float:left;'> # <label for='sin_fauna_evidente' style='float:left;padding-right:20px;'> # Sin fauna evidente # </label> # <input type='radio' name='fauna_evidente' value='no_encontrada' # id='sin_fauna_evidente' checked='true'/> # </div> # <div style='clear:both;'></div> # <br/> # <!--Para el fade-in/out:--> # <div id='info_fauna'> # <label for='nombre_comun' style='float:left;padding-right:49px;'> # Nombre común: # </label> # <input type='text' name='nombre_comun' class='string' # id='nombre_comun' value='datosArchivo.nombre_comun'/> # <br/> # <label for='nombre_cientifico' style='float:left;padding-right:37px;'> # Nombre científico: # </label> # <input type='text' name='nombre_cientifico' class='string' # id='nombre_cientifico' value='datosArchivo.nombre_cientifico'/> # <br/> # <label for='numero_individuos' style='float:left;padding-right:10px;'> # Número de individuos: # </label> # <input type='text' name='numero_individuos' class='integer' # id='numero_individuos' value='datosArchivo.numero_individuos'/> # </div> # <br/> # <input type='button' accesskey='a' style='float:left;' value='Anterior' id='anterior'/> # <input type='button' accesskey='s' style='float:right;' value='Siguiente' id='siguiente'/> # # <!--Se pone el center hasta el final, para que tome en cuenta el # margen del elemento que flota a la derecha. --> # # <center> # <input type='button' value='Enviar' id='enviar'/> # </center> # </form> # Obteniendo la información del conglomerado en el que se declararon los # archivos con el fin de reconstruir la ruta hacia ellos y poder visualizarlos. conglomeradoElegidoID = request.vars.conglomerado_muestra_id # Obteniendo la información del conglomerado datosConglomeradoAux = db( db.Conglomerado_muestra.id == conglomeradoElegidoID).select( db.Conglomerado_muestra.nombre, db.Conglomerado_muestra.fecha_visita) datosConglomerado = datosConglomeradoAux.first() datosConglomeradoNombre = str(datosConglomerado.nombre) datosConglomeradoFechaVisita = str(datosConglomerado.fecha_visita) # Creando el path hacia la imagen seleccionada (en caso de que se haya # seleccionado, recordar que el AJAX se activa para resetear la lista de # imágenes al cambiar cualquier combobox de la cascada). rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( datosConglomeradoNombre, datosConglomeradoFechaVisita) pathImagen = os.path.join(rutaCarpetaCglMuestra, 'c', datosArchivo.archivo) # Leyendo la imagen, pasándola a base 64 y guardándola en una variable # (hay que poner un try catch, por si no se puede leer la imagen). try: imagen = open(pathImagen, "rb") imagenCodificada = base64.b64encode(imagen.read()) except: imagenCodificada = "" revisionHTML = "<form id='forma_shadow'><input type='hidden' " +\ "name='id_archivo' value='" + str(datosArchivo.id) + "'/><center>" revisionHTML += "<img src='data:image/jpeg;base64," + imagenCodificada +\ "' alt='Error al cargar la fotografía' style='width:800px;height:600px;'/>" # Descomentar el código siguiente para utilizar la función download() de # Web2py para descargar la imagen en la vista (sólo funciona para imágenes # guardadas en "uploads" usando el método "store()" de Web2py.) #revisionHTML += "<img src='/init/02_camara/download/" + datosArchivo.archivo +\ # "' alt='Error al cargar la fotografía' style='width:800px;height:600px;'/>" revisionHTML += "</center><hr/><div style='float:left;padding-right:60px;'>" +\ "<label for='con_fauna_evidente' style='float:left;padding-right:20px;'>" +\ "Con fauna evidente</label><input type='radio' name='fauna_evidente' " +\ "value='encontrada' id='con_fauna_evidente'" # Si el campo de presencia de la foto elegida es True, entonces la # casilla "fauna evidente" aparece marcada. if datosArchivo.presencia: revisionHTML += " checked='true'/>" else: revisionHTML += "/>" revisionHTML += "</div><div style='float:left;'><label for='sin_fauna_evidente' " +\ "style='float:left;padding-right:20px;'>Sin fauna evidente</label><input type='radio' " +\ "name='fauna_evidente' value='no_encontrada' id='sin_fauna_evidente'" # Si el campo de presencia de la foto elegida es False, entonces la # casilla "Sin fauna evidente" aparece marcada. # Hay que revisar que sea igual a false, porque podría ser None. if datosArchivo.presencia == False: revisionHTML += " checked='true'/>" else: revisionHTML += "/>" revisionHTML += "</div><div style='clear:both;'></div><br/><div id='info_fauna'>" +\ "<label for='nombre_comun' style='float:left;padding-right:49px;'>" +\ "Nombre común:</label><input type='text' name='nombre_comun' class='string' " +\ "id='nombre_comun' value='" #Si hay nombre común, éste aparece en la casilla para ingresar el texto. if datosArchivo.nombre_comun: revisionHTML += datosArchivo.nombre_comun revisionHTML += "'/><br/><label for='nombre_cientifico' " +\ "style='float:left;padding-right:37px;'>Nombre científico:</label>" +\ "<input type='text' name='nombre_cientifico' class='string' id='nombre_cientifico' value='" #Si hay nombre científico, éste aparece en la casilla para ingresar el texto. if datosArchivo.nombre_cientifico: revisionHTML += datosArchivo.nombre_cientifico revisionHTML += "'/><br/><label for='numero_individuos' " +\ "style='float:left;padding-right:10px;'>Número de individuos:</label>" +\ "<input type='text' name='numero_individuos' class='integer' id='numero_individuos' value='" if datosArchivo.numero_individuos: revisionHTML += str(datosArchivo.numero_individuos) revisionHTML += "'/></div><br/>" +\ "<input type='button' accesskey='a' style='float:left;' value='Anterior' id='anterior'/>" +\ "<input type='button' accesskey='s' style='float:right;' value='Siguiente' id='siguiente'/>" +\ "<center><input type='button' value='Enviar' id='enviar'/></center>" +\ "</form>" return XML(revisionHTML)
def index2(): # Controlador correspondiente a la pestaña "Archivos de audio", de la sección ## "Grabadora": camposArchivosGrabadora = [ ########################################### # Archivos de la grabadora ########################################### # Localización de la grabadora. Por medio del conglomerado y sitio debe ser #posible localizar a lo más una grabadora. SELECT(_name='conglomerado_muestra_id', requires=IS_IN_DB(db,db.Conglomerado_muestra.id,'%(nombre)s')), SELECT(_name='sitio_muestra_id', requires=IS_IN_DB(db,db.Sitio_muestra.id,'%(nombre)s')), SELECT(_name='grabadora_id', requires=IS_IN_DB(db,db.Grabadora.id,'%(nombre)s')), # Elegir si se quieren registrar archivos audibles o ultrasónicos INPUT(_name='es_audible_ultrasonico',_type='string',requires=IS_NOT_EMPTY()), # Ahora ya no se envían los archivos a través de la forma, únicamente el # campo de "archivos_validados", y la información para construir la ruta # hacia la carpeta "nombre_aaa-mm-dd/t", donde se encuentran los archivos # a registrar en la base de datos. INPUT(_name='archivos_validados',_type='string',requires=IS_NOT_EMPTY()), INPUT(_name='conglomerado_muestra_nombre',_type='string', requires=IS_NOT_EMPTY()), INPUT(_name='conglomerado_muestra_fecha_visita',_type='string', requires=IS_NOT_EMPTY()), # INPUT(_name='archivos_grabadora',_type='file',requires=IS_NOT_EMPTY(), # _multiple=True) ] formaArchivosGrabadora = FORM(*camposArchivosGrabadora) if formaArchivosGrabadora.accepts(request.vars,formname='formaArchivosGrabadoraHTML'): ########################################### # Procesando los archivos múltiples capturados con una grabadora ########################################### # Revisando si los archivos subidos son audibles/ultrasónicos, mediante # la selección del usuario: if (formaArchivosGrabadora.vars['es_audible_ultrasonico'] == 'audible'): esAudible = True subcarpeta = "g_a" else: esAudible = False subcarpeta = "g_u" ########################################### # Procesando los archivos múltiples encontrados en la carpeta: # nombre_aaaa-mm-dd/subcarpeta ########################################### # Creando la ruta hacia la carpeta nombre_cgl_aaaa-mm-dd/subcarpeta. rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( str(formaArchivosGrabadora.vars['conglomerado_muestra_nombre']), str(formaArchivosGrabadora.vars['conglomerado_muestra_fecha_visita']) ) rutaT = os.path.join(rutaCarpetaCglMuestra, subcarpeta) # como ya se validó que la carpeta "nombre_aaaa-mm-dd/subcarpeta" exista, # la siguiente instrucción no tiene por qué tronar. archivos = os.listdir(rutaT) #archivos = formaArchivosGrabadora.vars['archivos_grabadora'] if not isinstance(archivos, list): archivos = [archivos] # como ya se validó que la carpeta "nombre_aaaa-mm-dd/c" sea no vacía, el # siguiente "for" no tiene por qué tronar. for aux in archivos: # Descomentar ésto para que Web2py guarde el archivo en la carpeta # "uploads" #archivoGrabadora = db.Archivo_grabadora.archivo.store(aux, aux.filename) # Excluyendo los archivos que no tienen terminación jpg o avi. # re.I: case insensitive. if re.search(r'wav$', aux, re.I): # Creando los campos de la tabla "Archivo_grabadora". datosArchivoGrabadora = {} datosArchivoGrabadora['es_audible'] = esAudible datosArchivoGrabadora['grabadora_id'] = formaArchivosGrabadora.vars['grabadora_id'] datosArchivoGrabadora['archivo'] = aux datosArchivoGrabadora['archivo_nombre_original'] = aux # Insertando el registro en la base de datos: db.Archivo_grabadora.insert(**datosArchivoGrabadora) response.flash = 'Éxito' elif formaArchivosGrabadora.errors: response.flash = 'Hubo un error al llenar la forma' else: pass ############################################################## # Procesando la información de la dropdown de conglomerado ############################################################## # Regresando los nombres de todos los conglomerados insertados en la tabla de # conglomerado junto con sus id's para llenar la combobox de conglomerado. listaConglomerado = db(db.Conglomerado_muestra).select( db.Conglomerado_muestra.id, db.Conglomerado_muestra.nombre) ############################################################## # Creando la tabla de revisión de los registros ingresados ############################################################## db.Archivo_grabadora.grabadora_id.writable = False grid = SQLFORM.smartgrid(db.Archivo_grabadora, orderby=~db.Archivo_grabadora.id,\ csv = False, user_signature = False, details = False, create = False, searchable = False, editable = False, maxtextlengths = {'Archivo_grabadora.archivo_nombre_original' : 50}) return dict(listaConglomerado = listaConglomerado, grid = grid)
def validarArchivos(): ## Función invocada mediante AJAX cuando se presiona el botón de "validar_archivos" ## en la forma, y además se encuentra un valor para "camara_id" (por lo que ## deben haberse seleccionado valores de "conglomerado_muestra_id" y ## "sitio_muestra_id"). Esta función valida: ## 1. Que el registro de los archivos no se haya realizado con anterioridad. ## 2. Que la carpeta nombre_cgl_aaaa-mm-dd/c exista. ## 3. Que dicha carpeta no esté vacía ## Regresa un JSON con: ## 1. El mensaje apropiado en cada caso, para que la vista ## lo alerte ## 2. Una bandera que indica si la validación fue exitosa o no ## 3. El "nombre" y la "fecha_visita" del conglomerado cuyo id fue recibido ## mediante AJAX, para no tener que recalcularlos en index2(). # Bandera que indica si los archivos fueron validados correctamente flag = 0 camaraElegidaID = request.vars.camara_id # Obteniendo los archivos correspondientes a la cámara seleccionada archivosCamara = db( db.Archivo_camara.camara_id == camaraElegidaID).select() datosConglomeradoNombre = "" datosConglomeradoFechaVisita = "" # Generando los distintos mensajes: if len(archivosCamara) > 0: mensaje = "Ya se han enviado los archivos de la cámara para el " +\ "conglomerado seleccionado. Si lo necesita, borre el registro de la cámara " +\ "en la sección de 'Revisar registros', y vuelva a declararla" else: # Obteniendo los datos del conglomerado seleccionado, con el fin de crear # el path hacia la carpeta apropiada: conglomeradoElegidoID = request.vars.conglomerado_muestra_id # Obteniendo la información del conglomerado datosConglomeradoAux = db( db.Conglomerado_muestra.id == conglomeradoElegidoID).select( db.Conglomerado_muestra.nombre, db.Conglomerado_muestra.fecha_visita) datosConglomerado = datosConglomeradoAux.first() datosConglomeradoNombre = str(datosConglomerado['nombre']) datosConglomeradoFechaVisita = str(datosConglomerado['fecha_visita']) # Creando la ruta hacia la carpeta nombre_cgl_aaaa-mm-dd/c rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( datosConglomeradoNombre, datosConglomeradoFechaVisita) rutaC = os.path.join(rutaCarpetaCglMuestra, 'c') #rutaCMensaje es la ruta C expresada para que el usuario la entienda rutaCMensaje = os.path.join( 'conglomerados', datosConglomeradoNombre + '_' + datosConglomeradoFechaVisita, 'c') # Verificando que dicha carpeta exista if not os.path.isdir(rutaC): mensaje = "No se encontró la carpeta " + rutaCMensaje +\ ". Favor de crearla." else: # Verificando que dicha carpeta contenga archivos jpg/avi: # Enlistando los archivos en rutaC lista_archivos = os.listdir(rutaC) # Obteniendo de éstos, cuáles son los archivos con terminación jpg/avi. lista_jpg_avi = [archivo\ for archivo in lista_archivos\ if re.search(r'(jp.?g|avi)$', archivo, re.I)] if len(lista_jpg_avi) == 0: mensaje = "La carpeta " + rutaCMensaje + " no contiene archivos " +\ "JPG/AVI, favor de agregarle las imágenes y videos." else: mensaje = "Validación exitosa para " + str(len(lista_jpg_avi)) +\ " archivos JPG/AVI en: " + rutaCMensaje + ". Ahora puede enviar la " +\ "información." flag = 1 # Enviando el diccionario como JSON para que JS lo pueda interpretar return json.dumps( dict(flag=flag, mensaje=mensaje, conglomerado_muestra_nombre=datosConglomeradoNombre, conglomerado_muestra_fecha_visita=datosConglomeradoFechaVisita))
def index2(): ## Controlador correspondiente a la pestaña "Archivos trampa cámara", de ## la sección "Trampa cámara" camposArchivosCamara = [ ########################################### # Archivos de la cámara ########################################### # Localización de la cámara. Por medio del conglomerado y sitio debe ser # posible localizar a lo más una cámara. SELECT(_name='conglomerado_muestra_id', requires=IS_IN_DB(db, db.Conglomerado_muestra.id, '%(nombre)s')), SELECT(_name='sitio_muestra_id', requires=IS_IN_DB(db, db.Sitio_muestra.id, '%(nombre)s')), SELECT(_name='camara_id', requires=IS_IN_DB(db, db.Camara.id, '%(nombre)s')), # Ahora ya no se envían los archivos a través de la forma, únicamente el # campo de "archivos_validados", y la información para construir la ruta # hacia la carpeta "nombre_aaa-mm-dd/c", donde se encuentran los archivos # a registrar en la base de datos. INPUT(_name='archivos_validados', _type='string', requires=IS_NOT_EMPTY()), INPUT(_name='conglomerado_muestra_nombre', _type='string', requires=IS_NOT_EMPTY()), INPUT(_name='conglomerado_muestra_fecha_visita', _type='string', requires=IS_NOT_EMPTY()), #INPUT(_name='archivos_camara',_type='file',requires=IS_NOT_EMPTY(), # _multiple=True) ] formaArchivosCamara = FORM(*camposArchivosCamara) if formaArchivosCamara.accepts(request.vars, formname='formaArchivosCamaraHTML'): ########################################### # Procesando los archivos múltiples encontrados en la carpeta: # nombre_aaaa-mm-dd/c ########################################### # Creando la ruta hacia la carpeta nombre_cgl_aaaa-mm-dd/c. rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( str(formaArchivosCamara.vars['conglomerado_muestra_nombre']), str(formaArchivosCamara.vars['conglomerado_muestra_fecha_visita'])) rutaC = os.path.join(rutaCarpetaCglMuestra, 'c') # como ya se validó que la carpeta "nombre_aaaa-mm-dd/c" exista, la # siguiente instrucción no tiene por qué tronar. archivos = os.listdir(rutaC) #archivos = formaArchivosCamara.vars['archivos_camara'] if not isinstance(archivos, list): archivos = [archivos] # como ya se validó que la carpeta "nombre_aaaa-mm-dd/c" sea no vacía, el # siguiente "for" no tiene por qué tronar. for aux in archivos: # Descomentar ésto para que Web2py guarde el archivo en la carpeta # "uploads" #archivoCamara = db.Archivo_camara.archivo.store(aux, aux.filename) # Excluyendo los archivos que no tienen terminación jpg o avi. # re.I: case insensitive. if re.search(r'(jp.?g|avi)$', aux, re.I): # Creando los campos de la tabla "Archivo_camara". datosArchivoCamara = {} datosArchivoCamara['camara_id'] = formaArchivosCamara.vars[ 'camara_id'] datosArchivoCamara['archivo'] = aux datosArchivoCamara['archivo_nombre_original'] = aux # Insertando el registro en la base de datos: db.Archivo_camara.insert(**datosArchivoCamara) response.flash = 'Éxito' elif formaArchivosCamara.errors: response.flash = 'Hubo un error al llenar la forma' else: pass ############################################################## # Procesando la información de la dropdown de conglomerado ############################################################## # Regresando los nombres de todos los conglomerados insertados en la tabla de # conglomerado junto con sus id's para llenar la combobox de conglomerado. listaConglomerado = db(db.Conglomerado_muestra).select( db.Conglomerado_muestra.id, db.Conglomerado_muestra.nombre) ############################################################## # Creando la tabla de revisión de los registros ingresados ############################################################## db.Archivo_camara.camara_id.writable = False grid = SQLFORM.smartgrid(db.Archivo_camara, orderby =~ db.Archivo_camara.id,\ csv = False, user_signature = False, details = False, create = False, searchable = False, editable = False, maxtextlengths = {'Archivo_camara.archivo_nombre_original' : 50}) return dict(listaConglomerado=listaConglomerado, grid=grid)
def asignarInformacionArchivo(): ## Ésta funcion se invoca mediante AJAX, y genera una forma para ## ingresar/modificar la información de la fotografía que seleccionó el ## usuario en el menú desplegable. El AJAX se activa al seleccionar un ## archivo de la lista desplegable. # Obteniendo la información del archivo que seleccionó el usuario: archivoElegidoID = request.vars.archivo_camara_id # Obteniendo la información del archivo datosArchivoAux = db(db.Archivo_camara.id == archivoElegidoID).select() datosArchivo = datosArchivoAux.first() # Creando la pantalla de revisión de archivos, considerando el caso en el # que datosArchivo esté vacía: if len(datosArchivoAux) == 0: revisionHTML = "<form id='forma_shadow'></form>" else: #HTML generado: # <form id='forma_shadow'> # <input type='hidden' name='id_archivo' value='str(datosArchivo.id)'/> # <center> # <img src='data:image/jpeg;base64,imagen_codificada' # alt='Error al cargar la fotografía' style='width:800px;height:600px;'/> # </center> # <hr/> # <div style='float:left;padding-right:60px;'> # <label for='con_fauna_evidente' style='float:left;padding-right:20px;'> # Con fauna evidente # </label> # <input type='radio' name='fauna_evidente' value='encontrada' # id='con_fauna_evidente' checked='true'/>" # </div> # <div style='float:left;'> # <label for='sin_fauna_evidente' style='float:left;padding-right:20px;'> # Sin fauna evidente # </label> # <input type='radio' name='fauna_evidente' value='no_encontrada' # id='sin_fauna_evidente' checked='true'/> # </div> # <div style='clear:both;'></div> # <br/> # <!--Para el fade-in/out:--> # <div id='info_fauna'> # <label for='nombre_comun' style='float:left;padding-right:49px;'> # Nombre común: # </label> # <input type='text' name='nombre_comun' class='string' # id='nombre_comun' value='datosArchivo.nombre_comun'/> # <br/> # <label for='nombre_cientifico' style='float:left;padding-right:37px;'> # Nombre científico: # </label> # <input type='text' name='nombre_cientifico' class='string' # id='nombre_cientifico' value='datosArchivo.nombre_cientifico'/> # <br/> # <label for='numero_individuos' style='float:left;padding-right:10px;'> # Número de individuos: # </label> # <input type='text' name='numero_individuos' class='integer' # id='numero_individuos' value='datosArchivo.numero_individuos'/> # </div> # <br/> # <input type='button' accesskey='a' style='float:left;' value='Anterior' id='anterior'/> # <input type='button' accesskey='s' style='float:right;' value='Siguiente' id='siguiente'/> # # <!--Se pone el center hasta el final, para que tome en cuenta el # margen del elemento que flota a la derecha. --> # # <center> # <input type='button' value='Enviar' id='enviar'/> # </center> # </form> # Obteniendo la información del conglomerado en el que se declararon los # archivos con el fin de reconstruir la ruta hacia ellos y poder visualizarlos. conglomeradoElegidoID = request.vars.conglomerado_muestra_id # Obteniendo la información del conglomerado datosConglomeradoAux = db( db.Conglomerado_muestra.id == conglomeradoElegidoID).select( db.Conglomerado_muestra.nombre, db.Conglomerado_muestra.fecha_visita) datosConglomerado = datosConglomeradoAux.first() datosConglomeradoNombre = str(datosConglomerado.nombre) datosConglomeradoFechaVisita = str(datosConglomerado.fecha_visita) # Creando el path hacia la imagen seleccionada (en caso de que se haya # seleccionado, recordar que el AJAX se activa para resetear la lista de # imágenes al cambiar cualquier combobox de la cascada). rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( datosConglomeradoNombre, datosConglomeradoFechaVisita) pathImagen = os.path.join(rutaCarpetaCglMuestra,'c',datosArchivo.archivo) # Leyendo la imagen, pasándola a base 64 y guardándola en una variable # (hay que poner un try catch, por si no se puede leer la imagen). try: imagen = open(pathImagen, "rb") imagenCodificada = base64.b64encode(imagen.read()) except: imagenCodificada = "" revisionHTML = "<form id='forma_shadow'><input type='hidden' " +\ "name='id_archivo' value='" + str(datosArchivo.id) + "'/><center>" revisionHTML += "<img src='data:image/jpeg;base64," + imagenCodificada +\ "' alt='Error al cargar la fotografía' style='width:800px;height:600px;'/>" # Descomentar el código siguiente para utilizar la función download() de # Web2py para descargar la imagen en la vista (sólo funciona para imágenes # guardadas en "uploads" usando el método "store()" de Web2py.) #revisionHTML += "<img src='/init/02_camara/download/" + datosArchivo.archivo +\ # "' alt='Error al cargar la fotografía' style='width:800px;height:600px;'/>" revisionHTML += "</center><hr/><div style='float:left;padding-right:60px;'>" +\ "<label for='con_fauna_evidente' style='float:left;padding-right:20px;'>" +\ "Con fauna evidente</label><input type='radio' name='fauna_evidente' " +\ "value='encontrada' id='con_fauna_evidente'" # Si el campo de presencia de la foto elegida es True, entonces la # casilla "fauna evidente" aparece marcada. if datosArchivo.presencia: revisionHTML += " checked='true'/>" else: revisionHTML += "/>" revisionHTML += "</div><div style='float:left;'><label for='sin_fauna_evidente' " +\ "style='float:left;padding-right:20px;'>Sin fauna evidente</label><input type='radio' " +\ "name='fauna_evidente' value='no_encontrada' id='sin_fauna_evidente'" # Si el campo de presencia de la foto elegida es False, entonces la # casilla "Sin fauna evidente" aparece marcada. # Hay que revisar que sea igual a false, porque podría ser None. if datosArchivo.presencia == False: revisionHTML += " checked='true'/>" else: revisionHTML += "/>" revisionHTML += "</div><div style='clear:both;'></div><br/><div id='info_fauna'>" +\ "<label for='nombre_comun' style='float:left;padding-right:49px;'>" +\ "Nombre común:</label><input type='text' name='nombre_comun' class='string' " +\ "id='nombre_comun' value='" #Si hay nombre común, éste aparece en la casilla para ingresar el texto. if datosArchivo.nombre_comun: revisionHTML += datosArchivo.nombre_comun revisionHTML += "'/><br/><label for='nombre_cientifico' " +\ "style='float:left;padding-right:37px;'>Nombre científico:</label>" +\ "<input type='text' name='nombre_cientifico' class='string' id='nombre_cientifico' value='" #Si hay nombre científico, éste aparece en la casilla para ingresar el texto. if datosArchivo.nombre_cientifico: revisionHTML += datosArchivo.nombre_cientifico revisionHTML += "'/><br/><label for='numero_individuos' " +\ "style='float:left;padding-right:10px;'>Número de individuos:</label>" +\ "<input type='text' name='numero_individuos' class='integer' id='numero_individuos' value='" if datosArchivo.numero_individuos: revisionHTML += str(datosArchivo.numero_individuos) revisionHTML += "'/></div><br/>" +\ "<input type='button' accesskey='a' style='float:left;' value='Anterior' id='anterior'/>" +\ "<input type='button' accesskey='s' style='float:right;' value='Siguiente' id='siguiente'/>" +\ "<center><input type='button' value='Enviar' id='enviar'/></center>" +\ "</form>" return XML(revisionHTML)
def validarArchivos(): ## Función invocada mediante AJAX cuando se presiona el botón de "validar_archivos" ## en la forma, y además se encuentra un valor para "camara_id" (por lo que ## deben haberse seleccionado valores de "conglomerado_muestra_id" y ## "sitio_muestra_id"). Esta función valida: ## 1. Que el registro de los archivos no se haya realizado con anterioridad. ## 2. Que la carpeta nombre_cgl_aaaa-mm-dd/c exista. ## 3. Que dicha carpeta no esté vacía ## Regresa un JSON con: ## 1. El mensaje apropiado en cada caso, para que la vista ## lo alerte ## 2. Una bandera que indica si la validación fue exitosa o no ## 3. El "nombre" y la "fecha_visita" del conglomerado cuyo id fue recibido ## mediante AJAX, para no tener que recalcularlos en index2(). # Bandera que indica si los archivos fueron validados correctamente flag = 0 camaraElegidaID = request.vars.camara_id # Obteniendo los archivos correspondientes a la cámara seleccionada archivosCamara = db(db.Archivo_camara.camara_id == camaraElegidaID).select() datosConglomeradoNombre = "" datosConglomeradoFechaVisita = "" # Generando los distintos mensajes: if len(archivosCamara) > 0: mensaje = "Ya se han enviado los archivos de la cámara para el " +\ "conglomerado seleccionado. Si lo necesita, borre el registro de la cámara " +\ "en la sección de 'Revisar registros', y vuelva a declararla" else: # Obteniendo los datos del conglomerado seleccionado, con el fin de crear # el path hacia la carpeta apropiada: conglomeradoElegidoID = request.vars.conglomerado_muestra_id # Obteniendo la información del conglomerado datosConglomeradoAux = db( db.Conglomerado_muestra.id == conglomeradoElegidoID).select( db.Conglomerado_muestra.nombre, db.Conglomerado_muestra.fecha_visita) datosConglomerado = datosConglomeradoAux.first() datosConglomeradoNombre = str(datosConglomerado['nombre']) datosConglomeradoFechaVisita = str(datosConglomerado['fecha_visita']) # Creando la ruta hacia la carpeta nombre_cgl_aaaa-mm-dd/c rutaCarpetaCglMuestra = eaa.crearRutaCarpeta( datosConglomeradoNombre, datosConglomeradoFechaVisita ) rutaC = os.path.join(rutaCarpetaCglMuestra, 'c') #rutaCMensaje es la ruta C expresada para que el usuario la entienda rutaCMensaje = os.path.join( 'conglomerados', datosConglomeradoNombre + '_' + datosConglomeradoFechaVisita, 'c') # Verificando que dicha carpeta exista if not os.path.isdir(rutaC): mensaje = "No se encontró la carpeta " + rutaCMensaje +\ ". Favor de crearla." else: # Verificando que dicha carpeta contenga archivos jpg/avi: # Enlistando los archivos en rutaC lista_archivos = os.listdir(rutaC) # Obteniendo de éstos, cuáles son los archivos con terminación jpg/avi. lista_jpg_avi = [archivo\ for archivo in lista_archivos\ if re.search(r'(jp.?g|avi)$', archivo, re.I)] if len(lista_jpg_avi) == 0: mensaje = "La carpeta " + rutaCMensaje + " no contiene archivos " +\ "JPG/AVI, favor de agregarle las imágenes y videos." else: mensaje = "Validación exitosa para " + str(len(lista_jpg_avi)) +\ " archivos JPG/AVI en: " + rutaCMensaje + ". Ahora puede enviar la " +\ "información." flag = 1 # Enviando el diccionario como JSON para que JS lo pueda interpretar return json.dumps(dict( flag = flag, mensaje = mensaje, conglomerado_muestra_nombre = datosConglomeradoNombre, conglomerado_muestra_fecha_visita = datosConglomeradoFechaVisita ))