HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Directory Organizer: Organizing a given directory by moving files into categories according to their type

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directoryintoaccordingtypefilesmovingcategoriesorganizingorganizergiven

Problem

My Windows desktop is messy with many files of different types here and there, therefore I thought of writing a program to organize it, and other directories too, for me. Here is my code:

```
import os
import shutil

class File:
"""Represents a computer file.

attributes: path, name, extension
"""
def __init__(self, path):
"""Inintializes a File object.

file_path: str
"""
if os.path.isfile(path):
self.path = path
self.name = os.path.basename(path)
self.extension = os.path.splitext(self.path)[1].lower()
else:
raise FileNotFoundError("This is not a valid file")

def is_document(self):
"""Returns whether file is a document."""
extensions = ('.htm', '.docx', '.docm', '.doc', '.dotx',
'.dotm', '.pdf', '.xps', '.rtf',
'.txt', '.xml', '.odt', '.wps', '.accdb',
'.mdb', '.adp', '.xlsx', '.xlsm', '.xls',
'.xlsb', '.xltx', '.xltm', '.xlt', '.htm'
'.csv', '.prn', '.dif', '.ods', '.xlam',
'.slk', '.pptx', '.pptm', '.ppt', '.potx',
'.potm', '.pot', '.ppsx', '.ppsm', '.epub')
return self.extension in extensions

def is_photo(self):
"""Returns whether file is a photo."""
extensions = ('.png', '.jpeg', '.jpg')
return self.extension in extensions

def is_media(self):
"""Returns whether file is a media file."""
extensions = ('.mp3', '.mp4', '.flv', '.amr', '.mpg', '.avi', '.mov', '.webm', '.rm')
return self.extension in extensions

def is_executable(self):
"""Returns whether file is an exeutable."""
return self.extension == '.exe'

def is_archive(self):
"""Returns whether file is a compressed file."""
extensions = ('.rar', '.zip')
return self.extension in extensions

def type(self):
"""Returns

Solution

There is quite a lot of repetition in the way you determine the file type. Plus, this approach does not scale well. What if you would have a dictionary of file type names as keys and a frozenset of extensions as values which you would dynamically transform into a map between an extension and a file type:

TYPE_EXTENSIONS = {
    'document': frozenset(['.htm', '.docx', '.docm', '.doc', '.dotx',
                           '.dotm', '.pdf', '.xps', '.rtf',
                           '.txt', '.xml', '.odt', '.wps', '.accdb',
                           '.mdb', '.adp', '.xlsx', '.xlsm', '.xls',
                           '.xlsb', '.xltx', '.xltm', '.xlt', '.htm'
                           '.csv', '.prn', '.dif', '.ods', '.xlam',
                           '.slk', '.pptx', '.pptm', '.ppt', '.potx',
                           '.potm', '.pot', '.ppsx', '.ppsm', '.epub']),
    'photo': frozenset(['.png', '.jpeg', '.jpg']),
    'media': frozenset(['.mp3', '.mp4', '.flv', '.amr', '.mpg', '.avi', '.mov', '.webm', '.rm']),
    'executable': frozenset(['.exe']),
    'archive': frozenset(['.rar', '.zip'])
}

EXTENSION_TYPES = {value: key 
                   for value in values
                   for key, values in TYPE_EXTENSIONS.items()}


Now, the type() method would simply look like:

def type(self):
    """Returns a string representing the type of file."""
    return EXTENSION_TYPES.get(self.extension, 'other')


And you would not need all the is_*() methods anymore.

Code Snippets

TYPE_EXTENSIONS = {
    'document': frozenset(['.htm', '.docx', '.docm', '.doc', '.dotx',
                           '.dotm', '.pdf', '.xps', '.rtf',
                           '.txt', '.xml', '.odt', '.wps', '.accdb',
                           '.mdb', '.adp', '.xlsx', '.xlsm', '.xls',
                           '.xlsb', '.xltx', '.xltm', '.xlt', '.htm'
                           '.csv', '.prn', '.dif', '.ods', '.xlam',
                           '.slk', '.pptx', '.pptm', '.ppt', '.potx',
                           '.potm', '.pot', '.ppsx', '.ppsm', '.epub']),
    'photo': frozenset(['.png', '.jpeg', '.jpg']),
    'media': frozenset(['.mp3', '.mp4', '.flv', '.amr', '.mpg', '.avi', '.mov', '.webm', '.rm']),
    'executable': frozenset(['.exe']),
    'archive': frozenset(['.rar', '.zip'])
}

EXTENSION_TYPES = {value: key 
                   for value in values
                   for key, values in TYPE_EXTENSIONS.items()}
def type(self):
    """Returns a string representing the type of file."""
    return EXTENSION_TYPES.get(self.extension, 'other')

Context

StackExchange Code Review Q#156481, answer score: 2

Revisions (0)

No revisions yet.