Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.albasani.net!news.stack.nl!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'example:': 0.03; 'else:': 0.03; 'elif': 0.05; 'root': 0.05; 'true,': 0.05; '"""': 0.07; 'modified': 0.07; 'none,': 0.07; 'none:': 0.07; '__init__': 0.09; 'caching,': 0.09; 'except:': 0.09; 'feature,': 0.09; 'filename': 0.09; 'function,': 0.09; 'naturally': 0.09; 'none):': 0.09; 'optimizing': 0.09; 'os.path': 0.09; 'prefix': 0.09; 'rewrite': 0.09; 'solution,': 0.09; 'try:': 0.09; 'unified': 0.09; 'python': 0.11; 'def': 0.12; 'wrote': 0.14; 'archive': 0.14; '"""#': 0.16; '"is': 0.16; 'benjamin': 0.16; 'code?': 0.16; 'dictionaries': 0.16; 'directory)': 0.16; 'false):': 0.16; 'filenames,': 0.16; 'files)': 0.16; 'folks,': 0.16; 'interest,': 0.16; 'key)': 0.16; 'lambda': 0.16; 'node.': 0.16; 'received:192.168.1.20': 0.16; 'simplified': 0.16; 'skip:g 50': 0.16; 'sorting.': 0.16; 'subdirectory': 0.16; 'true:': 0.16; 'url:py': 0.16; 'index': 0.16; 'ignore': 0.16; 'else,': 0.19; 'file,': 0.19; 'import': 0.22; 'separate': 0.22; 'to:name:python-list@python.org': 0.22; 'print': 0.22; 'exists': 0.24; 'package.': 0.24; 'subject:Code': 0.24; 'videos,': 0.24; 'file.': 0.24; 'sort': 0.25; 'class.': 0.26; 'extension': 0.26; 'skip:" 30': 0.26; 'pass': 0.26; 'skip:_ 20': 0.27; 'idea': 0.28; 'testing': 0.29; 'skip:p 30': 0.29; 'unix': 0.29; "i'm": 0.30; 'code': 0.31; 'directory,': 0.31; 'helpful.': 0.31; 'index,': 0.31; 'anyone': 0.31; 'file': 0.32; 'class': 0.32; '(e.g.': 0.33; 'raw': 0.33; 'skip:# 10': 0.33; 'skip:t 40': 0.33; 'device': 0.34; 'skip:_ 10': 0.34; 'info': 0.35; 'knows': 0.35; 'skip:s 30': 0.35; 'skip:u 20': 0.35; 'convert': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'add': 0.35; 'there': 0.35; 'version': 0.36; 'false': 0.36; 'gallery': 0.36; 'module.': 0.36; 'charset:us-ascii': 0.36; 'subject:?': 0.36; 'error.': 0.37; 'application': 0.37; 'list': 0.37; 'level': 0.37; 'list.': 0.37; 'clear': 0.37; 'being': 0.38; 'filter': 0.38; 'lists.': 0.38; 'to:addr:python-list': 0.38; 'files': 0.38; 'expect': 0.39; 'to:addr:python.org': 0.39; 'skip:u 10': 0.60; 'consists': 0.60; 'eventually': 0.60; 'url:u': 0.61; 'entire': 0.61; "you'll": 0.62; 'header:Message-Id:1': 0.63; 'information': 0.63; 'skip:n 10': 0.64; 'zip': 0.64; 'within': 0.65; 'managing': 0.66; 'due': 0.66; 'invalid': 0.68; 'friendly': 0.72; 'behavior': 0.77; 'low': 0.83; '"not': 0.84; 'directories,': 0.84; 'directory"': 0.84; 'music,': 0.84; 'skip:) 10': 0.84; 'stat': 0.84; 'url:self': 0.84; 'differences': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=schollnick.net; s=schollnick; h=sender:from:content-type:subject:message-id:date:to:mime-version; bh=xtoTJatf2L9qxnbZ5X8XoRWxYgfdBGTMXVjSG/Fa2TI=; b=SHHzcE3bjNv3XXbUaaq2KUEcNUIU+t2wyZo5z5RV/Uw4+DHYCbBDBlRhauNaPABQR2 FuiwXjNbavE5iQPHrrXn1W/0R47CwIvDK6GnWzT8d73oguA4VRdqFqi32gk8D/7YaKmG cMXdDFNOx8ssTc6RmLbBRT1dgSRY2e6lx7KAo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:content-type:subject:message-id:date :to:mime-version; bh=xtoTJatf2L9qxnbZ5X8XoRWxYgfdBGTMXVjSG/Fa2TI=; b=Pe47FRjpUzjdTTKzP5Oi2XBDzGtr+eepK2HLxlRTaRtjfEiFcIzOuH8QAEvfTaQkI/ 85OW6SSe1eO7GXjTlXfJeFm3+ZJeiPbXCeGGBIfEEDkoVZlfUy6xULeOwFPiW35wzcDq xNgAZUYMh5IW/1vGKOcPVWhhnxqhlRSmNBAeMuazx3zo+/fwbIzdWRUNdJJjQxAqiJjE PgmlkNCPVQLkPdgEv/byphbvKCqeH88ng4wShxRIzCqX4YHV7Mcq+T0IMJzpKNUz+SOB VgoAWBt4K4XGtJzR2HV0AUx9vm/79Za6tje/R51G5gdisYyoY96ysO6pXqhjhNzFbAkI f+8Q== X-Gm-Message-State: ALoCoQkUw26gC5qvdSjX2EiGsDuTf1w5IE2kvvx3ns8df5mhlwdCuwEiOj99iuBQ7Je2vrRJjdGJ X-Received: by 10.43.180.200 with SMTP id pf8mr634icc.50.1379772010407; Sat, 21 Sep 2013 07:00:10 -0700 (PDT) Sender: Benjamin Schollnick From: Benjamin Schollnick Content-Type: multipart/alternative; boundary="Apple-Mail=_8D268057-4031-4AEF-8235-6388AFB6FC78" Subject: Code suggestions? Date: Sat, 21 Sep 2013 10:00:06 -0400 To: "python-list@python.org" Mime-Version: 1.0 (Mac OS X Mail 6.5 \(1508\)) X-Mailer: Apple Mail (2.1508) X-Mailman-Approved-At: Sat, 21 Sep 2013 20:27:21 +0200 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 1151 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1379788042 news.xs4all.nl 16003 [2001:888:2000:d::a6]:34465 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:54562 --Apple-Mail=_8D268057-4031-4AEF-8235-6388AFB6FC78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Folks, I am re-writing an image gallery application that I wrote in Twisted. As part of this rewrite, I am attempting to simplify the process of = managing the directory listings. Would anyone have any suggestions on streamlining or optimizing this = code? The raw version of this file, is available from dropbox. https://dl.dropboxusercontent.com/u/241415/unified.py If you are testing with RAR files, you'll need rarfile.py https://dl.dropboxusercontent.com/u/241415/rarfile.py If anyone knows a better built-in Python 2.66/2.75 solution, that would = be helpful. =20 I eventually expect to support caching, but I think that will be an = application level feature, and not built-in to this module. The entire idea is to unify (thus unified.py) behavior better files, = directories, and archives. Yes, there is differences in the data coming back, but the calling = logic, is identical. So far, this rewrite has tremendously simplified the code for the image = gallery. If there is any interest, I'm willing to github unified or the = image gallery. =20 - Benjamin import os import os.path from stat import * import time class Unified_Directory: """ An Attempt to unify directories, and archives into one = single storage package. =09 For example: =09 gallery_listings =3D = unified.Unified_Directory () = gallery_listings.populate_file_data_from_filesystem ( filepathname =3D = directory_path) print "files: = ",gallery_listings.files,"/n/n" print "subdirectories: = ",gallery_listings.subdirectories, "/n/n" print "Display Gallery for ", = gallery_listings.root_path """ =09 def __init__ ( self ): self.rar_file_types =3D ['cbr', 'rar'] self.zip_file_types =3D ['cbz', = 'zip'] self.archive_file_types =3D self.rar_file_types = + self.zip_file_types =09 self.files_to_ignore =3D [] # = File filter to ignore =09 self.root_path =3D None = # This is the path in the OS that is being examined (e.g. = /Volumes/Users/username/ ) self.subdirectories =3D [] # = This is the subdirectories that exist in that path (e.g. Desktop, Music, = Videos, etc) =09 =09 self.files =3D [] = # This is the list of files that are in the root_path. = # Each file consists of a dictionary containing: = # = # * Filename = # * st_mode - Unix chmod = # * st_ino - inode number = # * st_dev - Unix Device = # * st_nlink - hard link count = # * st_uid - User/Owner ID = # * st_gid - Group ID of Owner = # * st_size - File size = # * st_atime - Last Access time = # * st_mtime - Last Modified Time = # * st_ctime - Last Metadata change = # * dot_extension - File extension = with . prefix (lower case) = # * file_extension - File Extension = without . prefix (lower case) =09 def _get_directory_list ( self, directory_to_list ): """ Returns the directories, and files in = separate lists. =09 Low Level function, intended to be used = by the populate function. """ directories =3D [] files =3D [] for fileobject in os.listdir ( = directory_to_list): if fileobject.lower() in = self.files_to_ignore: pass elif os.path.isdir ( directory_to_list + = os.sep + fileobject ): directories.append ( fileobject = ) else: files.append ( fileobject ) return (directories, files) def _return_directories_count ( self ): """ Return the number of directories that = are in the root path """ return len(self.subdirectories) =09 def _return_files_count ( self ): """ Return the number of files that are in = the root path """ return len(files) def is_file_archive ( self, filepathname =3D = None): """ Is the file that is being passed in, a = file in the self.archive_types.=20 =09 """ if filepathname =3D=3D None: return None else: extension =3D os.path.splitext ( = filepathname )[1][1:] if extension.lower() in = self.archive_file_types: return True else: return False def is_rar_file_archive ( self, filepathname = =3D None): """ Is the file that is being passed in, a = file in the self.rar_file_types list.=20 =09 """ if filepathname =3D=3D None: return None else: extension =3D os.path.splitext ( = filepathname )[1][1:] if extension.lower() in = self.rar_file_types: return True else: return False def is_zip_file_archive ( self, filepathname = =3D None): """ Is the file that is being passed in, a = file in the self.zip_file_types list.=20 """ if filepathname =3D=3D None: return None else: extension =3D os.path.splitext ( = filepathname )[1][1:] if extension.lower() in = self.zip_file_types: return True else: return False def natural_sort(self, l):=20 # # = http://stackoverflow.com/questions/4836710/does-python-have-a-built-in-fun= ction-for-string-natural-sort # import re convert =3D lambda text: int(text) if = text.isdigit() else text.lower()=20 alphanum_key =3D lambda key: [ convert(c) for c = in re.split('([0-9]+)', key) ]=20 return sorted(l, key =3D alphanum_key) =09 def return_file_index ( self, filename ): """ If the filename exists in the index, = then return the 0 based index of the file. =09 Else, return -1 on error. """ try: return self.files_index.index ( filename = ) except: return -1 =09 def populate_file_data_from_filesystem ( = self, filepathname =3D None, sorted=3DFalse, expand_archives =3D False): """ Populates this node. =09 Updates the self.files and self.subdirectories = dictionaries in the class. sorted - if true, will naturally sort the = filenames, and subdirectory names,=20 ensuring that they are = in a english friendly sorting. =09= =09 expand_archives - If true, will return the = listing of the zip or rar archive type. =09 """ # print "---",filepathname =09 filedata =3D {} # = Clear out old filedata # Set the root path, based off the = filepathname information =09 if filepathname =3D=3D None: # # Invalid request for data. = Return Empty data. # print "Returned due to None" return False self.root_path =3D os.path.split ( filepathname = )[0] if os.path.isdir ( filepathname ): # # Is directory, return all data on = the files within # self.subdirectories =3D [] # = Since we are now invoking, to re-populate, clear out all subdirectory = information self.subdirectory_index =3D [] self.files =3D [] = # Since we are now invoking, to re-populate, clear out all file = information self.files_index =3D [] =09 raw_directories, raw_files =3D = self._get_directory_list ( directory_to_list =3D filepathname ) for directory in raw_directories: directorydata =3D {} st =3D os.stat ( filepathname + = directory) # print "is directory" # print st dir_subdirectories, dir_files =3D = self._get_directory_list ( filepathname + directory ) =09 directorydata [ "directoryname"] = =3D directory directorydata [ = "parentdirectory" ] =3D os.path.split (filepathname) directorydata [ "st_mode" ] = =3D st[ST_MODE] directorydata [ "st_inode" ] =3D = st[ST_INO] directorydata [ "st_dev" ] = =3D st[ST_DEV] directorydata [ "st_nlink" ] =3D = st[ST_NLINK] directorydata [ "st_uid" ] = =3D st[ST_UID] directorydata [ "st_gid" ] = =3D st[ST_GID] directorydata [ "compressed" ] = =3D st[ST_SIZE] directorydata [ "st_size" ] = =3D 0#os.path.getsize ( filepathname )#st[ST_SIZE] directorydata [ "st_atime" ] =3D = st[ST_ATIME] directorydata [ "raw_st_mtime" ] = =3D st[ST_MTIME] directorydata [ "st_mtime" ] =3D = time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME] directorydata [ "st_ctime" ] =3D = st[ST_CTIME] directorydata [ "dot_extension" = ] =3D ".dir" directorydata [ "file_extension" = ] =3D "dir" directorydata [ "number_files" ] = =3D len(dir_files) directorydata [ "number_dirs" ] = =3D len(dir_subdirectories) =09 self.subdirectories.append ( = directorydata) self.subdirectory_index.append ( = directory ) for x in raw_files: # # Take each file in the = directory, and add it to the files listing # = self.populate_file_data_from_filesystem ( filepathname =3D filepathname = + os.sep + x ) self.files_index.append ( x ) =09 return if os.path.isfile ( filepathname ): if self.is_file_archive ( filepathname ) = and expand_archives =3D=3D True: # print "archive" if self.is_rar_file_archive = ( filepathname ): # print "processing rar" rar_filepathname =3D = filepathname import rarfile archivefile =3D = rarfile.RarFile ( rar_filepathname, 'r') # print "processing zip" elif self.is_zip_file_archive ( = filepathname ): zip_filepathname =3D = filepathname import zipfile archivefile =3D = zipfile.ZipFile ( zip_filepathname, 'r') # print "processing zip" infolist =3D = archivefile.infolist () for info in infolist: filedata =3D {} filedata [ "filename" ] = =3D info.filename filedata [ = "archivefilename" ] =3D filepathname filedata [ "st_mode" ] = =3D None filedata [ "st_inode" ] = =3D None filedata [ "st_dev" ] = =3D None filedata [ "st_nlink" ] = =3D None filedata [ "st_uid" ] = =3D None filedata [ "st_gid" ] = =3D None filedata [ "st_size" ] = =3D info.file_size filedata [ "compressed" = ] =3D info.compress_size filedata [ "st_atime" ] = =3D None filedata [ = "raw_st_mtime" ] =3D st[ST_MTIME] filedata [ "st_mtime" ] = =3D time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME] filedata [ "st_ctime" ] = =3D st[ST_CTIME] filedata [ "st_ctime" ] = =3D None filedata [ = "dot_extension" ] =3D os.path.splitext ( info.filename )[1].lower() filedata [ = "file_extension" ] =3D os.path.splitext ( info.filename )[1][1:].lower() self.files.append ( = filedata ) else: # print "not archive" st =3D os.stat ( filepathname ) filedata [ "filename" ] =3D = os.path.split (filepathname)[1] filedata [ "fq_filename" ] =3D = filepathname filedata [ "st_mode" ] =3D = st[ST_MODE] filedata [ "st_inode" ] =3D = st[ST_INO] filedata [ "st_dev" ] =3D = st[ST_DEV] filedata [ "st_nlink" ] =3D = st[ST_NLINK] filedata [ "st_uid" ] =3D = st[ST_UID] filedata [ "st_gid" ] =3D = st[ST_GID] filedata [ "compressed" ] = =3D st[ST_SIZE] filedata [ "st_size" ] =3D = st[ST_SIZE] filedata [ "st_atime" ] =3D = st[ST_ATIME] filedata [ "raw_st_mtime" ] =3D = st[ST_MTIME] filedata [ "st_mtime" ] =3D = time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME] filedata [ "st_ctime" ] =3D = st[ST_CTIME] filedata [ "dot_extension" ] =3D = os.path.splitext ( filepathname )[1].lower() filedata [ "file_extension" ] =3D = os.path.splitext ( filepathname )[1][1:].lower() self.files.append ( filedata ) if sorted: self.natural_sort ( = self.files_index ) self.natural_sort ( = self.subdirectory_index ) =09 return True= --Apple-Mail=_8D268057-4031-4AEF-8235-6388AFB6FC78 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii https://dl.= dropboxusercontent.com/u/241415/unified.py

If= you are testing with RAR files, you'll need = rarfile.py


If= anyone knows a better built-in Python 2.66/2.75 solution, that would be = helpful.  

I eventually expect to support = caching, but I think that will be an application level feature, and not = built-in to this module.

The entire idea is to = unify (thus unified.py) behavior better files, directories, and = archives.

Yes, there is differences in the data = coming back, but the calling logic, is = identical.

So far, this rewrite has = tremendously simplified the code for the image gallery.  If there = is any interest, I'm willing to github unified or the image gallery. =  

- = Benjamin

import os
import = os.path
from stat import *
import = time
class = Unified_Directory:
"""
= An Attempt to unify directories, and archives into one single = storage package.
= For example:
= = gallery_listings =3D unified.Unified_Directory ()
= gallery_listings.populate_file_data_from_filesystem ( = filepathname =3D directory_path)
print = "files: ",gallery_listings.files,"/n/n"
= print "subdirectories: ",gallery_listings.subdirectories, = "/n/n"
  print = "Display Gallery for ", = gallery_listings.root_path

= """
= def = __init__ ( self ):
= self.rar_file_types =3D ['cbr', = 'rar']
= self.zip_file_types =3D= ['cbz', 'zip']
= self.archive_file_types =3D self.rar_file_types + = self.zip_file_types
= self.files_to_ignore =3D [] # = = File filter to ignore
= self.root_path =3D None = # = This is the path in the OS that is being examined (e.g. = /Volumes/Users/username/ )
= self.subdirectories =3D [] = # = This is the subdirectories that exist in that path (e.g. Desktop, = Music, Videos, etc)
=
self.files = =3D [] = # = This is the list of files that are in the = root_path.
= # Each file = consists of a dictionary containing:
= = #
= # * = Filename
= # * = st_mode = - Unix chmod
= # * = st_ino - = inode number
= # * = st_dev - = Unix Device
= # * = st_nlink = - hard link count
= # * = st_uid - = User/Owner ID
= # * = st_gid - = Group ID of Owner
= # * = st_size = - File size
= # * = st_atime = - Last Access time
= # * = st_mtime = - Last Modified Time
= # * = st_ctime = - Last Metadata change
= # * = dot_extension = - File extension with . prefix (lower case)
= = # = * file_extension - File Extension without . prefix = (lower case)
= def = _get_directory_list ( self, directory_to_list ):
= """
Returns = the directories, and files in separate lists.
=
Low Level = function, intended to be used by the populate function.
= """
directories =3D = []
= files =3D []
= for fileobject in os.listdir ( = directory_to_list):
if = fileobject.lower() in self.files_to_ignore:
= pass
elif = os.path.isdir ( directory_to_list + os.sep + fileobject = ):
= directories.append ( fileobject = )
= else:
= files.append ( fileobject )
= return (directories, files)

= def = _return_directories_count ( self ):
= """
Return = the number of directories that are in the root path
= """
return = len(self.subdirectories)
= def = _return_files_count ( self ):
= """
Return = the number of files that are in the root path
= """
return = len(files)

def = is_file_archive ( self, filepathname =3D None):
= """
Is the = file that is being passed in, a file in the = self.archive_types. 
=
= """
if filepathname = =3D=3D None:
return = None
= else:
extension = =3D os.path.splitext ( filepathname )[1][1:]
= if extension.lower() in self.archive_file_types:
= return True
= else:
= return False

= def = is_rar_file_archive ( self, filepathname =3D = None):
= """
= Is the file that is being passed in, a file in the = self.rar_file_types list. 
=
= """
if filepathname = =3D=3D None:
return = None
= else:
extension = =3D os.path.splitext ( filepathname )[1][1:]
= if extension.lower() in self.rar_file_types:
= return True
= else:
= return False

= def = is_zip_file_archive ( self, filepathname =3D = None):
= """
= Is the file that is being passed in, a file in the = self.zip_file_types list. 
= """
if filepathname = =3D=3D None:
return = None
= else:
extension = =3D os.path.splitext ( filepathname )[1][1:]
= if extension.lower() in self.zip_file_types:
= return True
= else:
= return False


= def natural_sort(self, l): 
= #
# http://stackoverflow.com/questions/= 4836710/does-python-have-a-built-in-function-for-string-natural-sort
= #
import = re
= convert =3D lambda text: int(text) if text.isdigit() else = text.lower() 
alphanum_key =3D = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) = ] 
return sorted(l, = key =3D alphanum_key)
= def = return_file_index ( self, filename ):
= """
If the = filename exists in the index, then return the 0 based index of the = file.
=
Else, = return -1 on error.
= """
= try:
return = self.files_index.index ( filename )
= except:
return = -1
=
def = populate_file_data_from_filesystem ( self, filepathname =3D None, = sorted=3DFalse, expand_archives =3D False):
= """
Populates this = node.
=
Updates the = self.files and self.subdirectories dictionaries in the = class.

sorted - if true, = will naturally sort the filenames, and subdirectory = names, 
= ensuring that they are in a english friendly sorting. =
=
expand_archives - = If true, will return the listing of the zip or rar archive = type.
=
= """
# print = "---",filepathname
=
filedata =3D = {} = # = Clear out old filedata

= # = Set the root path, based off the filepathname = information
= if filepathname =3D=3D None:
= #
# Invalid = request for data.  Return Empty data.
= #
print = "Returned due to None"
return = False

self.root_path =3D = os.path.split ( filepathname )[0]
if os.path.isdir = ( filepathname ):
= #
# Is = directory, return all data on the files within
= #
= self.subdirectories =3D [] # Since we are now invoking, to = re-populate, clear out all subdirectory information
= self.subdirectory_index =3D []
= self.files =3D [] # Since we = are now invoking, to re-populate, clear out all file = information
= self.files_index =3D []
=
= raw_directories, raw_files =3D self._get_directory_list ( = directory_to_list =3D filepathname )

= for directory in raw_directories:
= directorydata =3D {}
= st =3D os.stat ( filepathname + = directory)
# = print "is directory"
# = print st
= dir_subdirectories, dir_files =3D self._get_directory_list ( = filepathname + directory )
=
= directorydata [ "directoryname"]    =3D = directory
= directorydata [ "parentdirectory" ] =3D os.path.split = (filepathname)
= directorydata [ "st_mode" ] =3D st[ST_MODE]
= directorydata [ "st_inode" ] =3D = st[ST_INO]
= directorydata [ "st_dev" ] =3D st[ST_DEV]
= directorydata [ "st_nlink" ] =3D = st[ST_NLINK]
= directorydata [ "st_uid" ] =3D st[ST_UID]
= directorydata [ "st_gid" ] =3D st[ST_GID]
= directorydata [ "compressed" ] =3D = st[ST_SIZE]
= directorydata [ "st_size" ] =3D 0#os.path.getsize ( = filepathname )#st[ST_SIZE]
= directorydata [ "st_atime" ] =3D st[ST_ATIME]
= directorydata [ "raw_st_mtime" ] =3D = st[ST_MTIME]
= directorydata [ "st_mtime" ] =3D = time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME]
= directorydata [ "st_ctime" ] =3D = st[ST_CTIME]
= directorydata [ "dot_extension" ] =3D ".dir"
= directorydata [ "file_extension" ] =3D = "dir"
= directorydata [ "number_files" ] = =3D len(dir_files)
= directorydata [ "number_dirs" ] =3D = len(dir_subdirectories)
= self.subdirectories.append ( = directorydata)
= self.subdirectory_index.append ( directory = )

for x in = raw_files:
= #
= # = Take each file in the directory, and add it to the files = listing
= #
= self.populate_file_data_from_filesystem ( filepathname =3D = filepathname + os.sep + x )
= self.files_index.append ( x )
=
= return

if os.path.isfile = ( filepathname ):
if self.is_file_archive ( filepathname ) and = expand_archives =3D=3D True:
# = print "archive"
= if = self.is_rar_file_archive ( = filepathname ):
# = print "processing rar"
= rar_filepathname =3D filepathname
= import rarfile
= archivefile =3D rarfile.RarFile ( = rar_filepathname, 'r')
# = print "processing zip"
= elif self.is_zip_file_archive ( = filepathname ):
= zip_filepathname =3D filepathname
= import zipfile
= archivefile =3D zipfile.ZipFile ( = zip_filepathname, 'r')
# = print "processing zip"

= infolist =3D archivefile.infolist ()
= for info in infolist:
= filedata =3D {}
= filedata [ "filename" ] =3D = info.filename
= filedata [ "archivefilename" ] =3D filepathname
= filedata [ "st_mode" ] =3D = None
= filedata [ "st_inode" ] =3D= None
= filedata [ "st_dev" ] = =3D= None
= filedata [ "st_nlink" ] =3D= None
= filedata [ "st_uid" ] = =3D= None
= filedata [ "st_gid" ] = =3D= None
= filedata [ "st_size" ] = =3D= info.file_size
= filedata [ "compressed" ] =3D = info.compress_size
= filedata [ "st_atime" ] =3D None
= filedata [ "raw_st_mtime" ] =3D = st[ST_MTIME]
= filedata [ "st_mtime" ] =3D = time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME]
= filedata [ "st_ctime" ] =3D = st[ST_CTIME]
= filedata [ "st_ctime" ] =3D None
= filedata [ "dot_extension" ] =3D os.path.splitext = ( info.filename )[1].lower()
= filedata [ "file_extension" ] =3D os.path.splitext ( = info.filename )[1][1:].lower()
= self.files.append ( filedata )
= else:
# = print "not archive"
= st =3D os.stat ( filepathname )
= filedata [ "filename" ] =3D os.path.split = (filepathname)[1]
= filedata [ "fq_filename" ] =3D filepathname
= filedata [ "st_mode" ] =3D st[ST_MODE]
= filedata [ "st_inode" ] =3D st[ST_INO]
= filedata [ "st_dev" ] =3D st[ST_DEV]
= filedata [ "st_nlink" ] =3D st[ST_NLINK]
= filedata [ "st_uid" ] =3D st[ST_UID]
= filedata [ "st_gid" ] =3D st[ST_GID]
= filedata [ "compressed" ] =3D st[ST_SIZE]
= filedata [ "st_size" ] =3D st[ST_SIZE]
= filedata [ "st_atime" ] =3D st[ST_ATIME]
= filedata [ "raw_st_mtime" ] =3D = st[ST_MTIME]
= filedata [ "st_mtime" ] =3D = time.asctime(time.localtime(st[ST_MTIME])) #st[ST_MTIME]
= filedata [ "st_ctime" ] =3D st[ST_CTIME]
= filedata [ "dot_extension" ] =3D os.path.splitext ( = filepathname )[1].lower()
= filedata [ "file_extension" ] =3D os.path.splitext ( filepathname = )[1][1:].lower()
= self.files.append ( filedata )

= if sorted:
= self.natural_sort ( self.files_index )
= self.natural_sort ( self.subdirectory_index = )
=
return = True
= --Apple-Mail=_8D268057-4031-4AEF-8235-6388AFB6FC78--