Веб-загрузку кириллица-по имени изображения


Для веб-загрузки кириллица-по имени изображения, я написал следующий скрипт:

#!/usr/bin/python
# coding=utf-8

import os
import argparse
import shutil

class Error: pass
class FolderError(Error): pass

def copytranstree (src, dst):
   names = os.listdir( src )

   try:
       os.makedirs( dst )
   except WindowsError:
       pass

   errors = []

   for name in names:

       srcname = os.path.join( src, name )

       dstname = os.path.join( dst, ''.join([translit.get(x, x) for x in name.decode( input_parametres.encoding ).lower()]).encode( input_parametres.encoding ) )

       try:
           if os.path.isdir( srcname ):
               copytranstree( srcname, dstname )
           else:
               shutil.copy2( srcname, dstname )
       except (IOError, os.error), why:
           errors.append( ( srcname, dstname, str( why ) ))
       except Error, err:
           errors.extend( err.args[0] )

   try:
       shutil.copystat( src, dst )
   except WindowsError:
       pass
   except OSError, why:
       errors.extend( (src, dst, str(why) ) )
   if errors:
       raise Error( errors )

parser = argparse.ArgumentParser(description='Copy directory tree with transliterated pathnames')
parser.add_argument('-e','--encoding', help='File system encoding', default='utf-8')
parser.add_argument('-s','--src', help='Source folder name', default='./' )
parser.add_argument('-d','--dst', help='Destination folder name', default='./')

input_parametres = parser.parse_args()

translit = dict(zip(u"абвгдеёзийклмнопрстуфхьъ", "abvgdeeziyklmnoprstufh'~"))
translit.update({u'ц': 'tz', u'ч': 'ch', u'ш': 'sh', u'ы': 'yi',
                u'э': 'ye', u'ю': 'ju', u'я': 'ja', u' ': '_'})

src = os.path.abspath( input_parametres.src )
dst = os.path.abspath( input_parametres.dst )

if not os.path.exists( dst ):
   dstname = ''.join([translit.get(x, x) for x in dst.decode( input_parametres.encoding ).lower()]).encode( input_parametres.encoding ).lower()
   os.makedirs( dstname )
   dst = os.path.abspath( dstname )

if not os.path.exists( src ) or os.path.isfile( dst ):
   raise FolderError()

copytranstree( src, dst )

В транслитерирует сценария и копии дерева файлов из папки источника к получателю, учитывая кодирование передаваемых в скрипт (в кодировке UTF для Ubuntu, CP121 для Windows).

Какие-то идеи для общего улучшения структуры для ОС Linux?



1646
8
задан 21 апреля 2011 в 01:04 Источник Поделиться
Комментарии
1 ответ


  1. Все исключения в Python должны
    наследовать от класса exception.

  2. Об ошибках Windows работает только на Windows, его лучше использовать более общие OSError

  3. Вы дважды имеют очень длинную линию транслитерации строку. Поместить его в функцию и вызвать ее

  4. Вы должны поместить код, который является частью скрипта в функцию main.

  5. Вы не должны бросать исключения, которые вы знаете, не будет пойман.

  6. Как вы собираете ошибки, бросая их вверх по стеку-это некрасиво.

  7. Если вы разделяете логику ходьбы от операции файл логика кода будет понятнее.

Мои обновления (совершенно непроверенных и, наверное, неправильно):

#!/usr/bin/python
# coding=utf-8

import os
import argparse
import shutil

class CommandError(Exception):
"""
Thrown when the user has made a mistake in the command line
"""

def transliterated_walk(encoding, src, dst):
"""
A generator which will walk over src producing them
along with the transliterated versions in dst
"""
files = []
for filename in os.listdir(src):
src_path = os.path.join(src, filename)
dest_path = os.path.join(dest, transliterated(encoding, filename))

if os.path.isdir(path):
for entry in transliterated_walk(encoding, src_path, dest_path):
yield entry
else:
files.append( (src_path, dest_path) )
yield src, dest, files

def copytranstree (encoding, src, dst):
errors = []

for src_path, dest_path, filenames in transliterated_walk(encoding, src, dest):
try:
os.makedirs( dest_path )
except WindowsError:
pass

for src_filename, dest_filename in filenames:
try:
shutil.copy2( src_filename, dst_filename )
except (IOError, os.error) as why:
errors.append( (src_filename, dest_filename, str(why) )

try:
shutil.copystat( src, dst )
except OSError as why:
errors.append( (src_path, dst_path, str(why) ) )

TRANSLIT = dict(zip(u"абвгдеёзийклмнопрстуфхьъ", "abvgdeeziyklmnoprstufh'~"))
TRANSLIT.update({u'ц': 'tz', u'ч': 'ch', u'ш': 'sh', u'ы': 'yi',
u'э': 'ye', u'ю': 'ju', u'я': 'ja', u' ': '_'})

def transliterate(encoding, string):
decoded = string.decode(encoding).lower()
transliterated = ''.join(translit.get(x, x) for x in decoded)
return transliterated.encode(encoding).lower()

def main():
try:
parser = argparse.ArgumentParser(description='Copy directory tree with transliterated pathnames')
parser.add_argument('-e','--encoding', help='File system encoding', default='utf-8')
parser.add_argument('-s','--src', help='Source folder name', default='./' )
parser.add_argument('-d','--dst', help='Destination folder name', default='./')

input_parametres = parser.parse_args()

src = os.path.abspath( input_parametres.src )
dst = os.path.abspath( input_parametres.dst )

if not os.path.exists( dst ):
dstname = transliterate(dst)
os.makedirs( dstname )
dst = os.path.abspath( dstname )

if not os.path.exists( src ):
raise CommandError('%s does not exist' % src)
if os.path.isfile( dst ):
raise CommandError('%s is a file' % dest)

copytranstree( encoding, src, dst )
except CommandError as error:
print error

if __name__ == '__main__':
main()

8
ответ дан 21 апреля 2011 в 04:04 Источник Поделиться