[Python-es] Re: Re: Codificacion y nombres de archivos

Oswaldo Hernández listas en soft-com.es
Mar Jun 19 13:07:51 CEST 2007


Gabriel Genellina escribió:
> En Mon, 18 Jun 2007 15:58:15 -0300, Oswaldo Hernández 
> <listas en soft-com.es> escribió:
> 
>> try:
>>         # comprobar si ya esta en la codificacion destino
>>         if src.encode(COD_DESTINO) == src:
> 
> Esta es la linea donde se usa implicitamente el defaultencoding, y por 
> eso solo te funciona en utf-8.
> src es string. src.encode primero convierte internamente string a 
> unicode usando el default (modificado a utf8), luego convierte unicode a 
> string usando COD_DESTINO.
> O sea, en realidad esta haciendo:
> if src.decode(sys.getdefaultencoding()).encode(COD_DESTINO) == src:
> if src.decode("utf-8").encode(COD_DESTINO) == src:
> 

Esto del encode y decode es un lio, pero parece que voy entendiendolo mejor.
He modificado la linea en cuestion a
	if src.decode(COD_DESTINO).encode(COD_DESTINO):

He vuelto a reconfigurar el site.py para volver a ponerlo como ascii y funciona bien con cualquiera 
de las dos codificaciones.

Adjunto el script tal como ha quedado.

Gracias de nuevo.

-- 
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
------------ próxima parte ------------
#!/usr/bin/python
# -*- coding: UTF-8 -*-

# Recodificacion de nombres de archivos y directorios

# 19-06-07 Corregido problema de comprobar la codificacion actual del archivo 
# 			cuando el defaultencoding != getfilesystemencoding gracias a Grabriel

import os
import sys

ruta = "/home/datos"	# ruta inicial
COD_ORIGEN = "cp850"	# codificacion actual de los nombres de archivo y directorio
COD_DESTINO = sys.getfilesystemencoding()	# codificacion destino (UTF-8)

print "Recodificacion de nombres de archivo y directorio"
print "%s -> %s" % (COD_ORIGEN, COD_DESTINO)

print "\nConfiguracion local:"
print "\tdefaultencoding:%s\n\tfilesystemencoding:%s\n" % (sys.getdefaultencoding(), sys.getfilesystemencoding())



def recodifica(src):
	# comprobacion de encoding
	# devuelve la cadena recodificada si su codificacion no es COD_DESTINO
	# OJO, puede ser no del todo fiable, hacer siempre copia de seguridad antes del proceso

	try:
		# comprobar si ya esta en la codificacion destino
		if src.decode(COD_DESTINO).encode(COD_DESTINO):
			return src	# OK, misma codificacion

		# No hay error pero son distintos ????, intenta recodificar
		return src.decode(COD_ORIGEN).encode(COD_DESTINO)

	except UnicodeDecodeError:
		# recodificar
		return src.decode(COD_ORIGEN).encode(COD_DESTINO)

	except Exception, e:
		# ??? puede que la codificacion de origen no sea correcta ???
		print "Error <%s> al intentar recodificar:%s " % (e, src)
		raise
		
print " ---------------- DIRECTORIOS ------------------"
# la iteracion dinamica de walk puede hacer que si modificamos un directorio, no vea los subdirectorios que contiene
# se repite el proceso hasta que no quede nada por hacer
while 1:
	algohecho = False
	for root, dirs, files in os.walk(ruta):	
		for dir in dirs:
			dir_dest = recodifica(dir)
			if dir_dest != dir:
				origen = os.path.join(root, dir)
				destino = os.path.join(root, dir_dest)
				print "renombar directorio:\n%s\n-> %s\n" % (origen, destino)
				os.rename(origen, destino)
				# activar flag
				algohecho = True

	if not algohecho:
		break
	
		
print " ----------------- ARCHIVOS --------------------"
for root, dirs, files in os.walk(ruta):	
	for archivo in files:
		f_dest = recodifica(archivo)
		if f_dest != archivo:
			origen = os.path.join(root, archivo)
			destino = os.path.join(root, f_dest)
			print "renombrar archivo:\n%s\n-> %s\n" % (origen, destino)
			os.rename(origen, destino)
				
print "Hecho :)"			




Más información sobre la lista de distribución Python-es