How to unlock locked files and folders (mac) using Python

As a “cleanup” after completing my main goal of the script, a function is called to recursively scan each folder and delete all files that end in a predefined set of extensions.

I have during my testing found that some files with the file extension in the list of those to be removed, actually cause an error: [Errno 1] Operation not permitted: '/location/of/locked/file.png. Looking at the file itself, it looks locked (on Mac).

  • How can I remove a locked attribute (if one exists) from each file / folder using Python and then delete the file if it ends in the extension?
    Preferably, all this can be done in the same function below, since it takes a lot of time to go through the input directory — processing each one only once is the way to go.
  • How does this affect script integrity on Windows?
    I took care of programming in such a way that it is compatible between the OS, but as far as I know, a locked attribute does not exist on Windows, as is done on a Mac, and can cause unknown side effects.

REMOVE_FILETYPES = ('.png', '.jpg', '.jpeg', '.pdf')

def cleaner(currentPath):
  if not os.path.isdir(currentPath):
    if currentPath.endswith(REMOVE_FILETYPES) or os.path.basename(currentPath).startswith('.'):
      try:
        os.remove(currentPath)
        print('REMOVED: \"{removed}\"'.format(removed = currentPath))
      except BaseException as e:
        print('ERROR: Could not remove: \"{failed}\"'.format(failed = str(e)))
      finally:
        return True
    return False

  if all([cleaner(os.path.join(currentPath, file)) for file in os.listdir(currentPath)]):
    try:
      os.rmdir(currentPath)
      print('REMOVED: \"{removed}\"'.format(removed = currentPath))
    except:
      print('ERROR: Could not remove: \"{failed}\"'.format(failed = currentPath))
    finally:
      return True
  return False

cleaner(r'/path/to/parent/dir')

I would really appreciate it if someone could show me how to integrate such functions into a routine. Greetings.


EDIT: Remote error handling on request

def cleaner(currentPath):
if sys.platform == 'darwin':
    os.system('chflags nouchg {}'.format(currentPath))
if not os.path.isdir(currentPath):
    if currentPath.endswith(REMOVE_FILETYPES) or os.path.basename(currentPath).startswith('.'):
        try:
            os.remove(currentPath)
            print('REMOVED: \"{removed}\"'.format(removed=currentPath))
        except PermissionError:
            if sys.platform == 'darwin':
                os.system('chflags nouchg {}'.format(currentPath))
                os.remove(currentPath)
if all([cleaner(os.path.join(currentPath, file)) for file in os.listdir(currentPath)]) and not currentPath == SOURCE_DIR:
    os.rmdir(currentPath)
    print('REMOVED: \"{removed}\"'.format(removed=currentPath))
+4
1

chflags:

os.system('chflags nouchg {}'.format(filename))

( os.chflags, , , , os " " , , os.stat(locked_filename).st_flags.)

, chflags except: , , :

try:
    os.remove(currentPath)
    print('REMOVED: \"{removed}\"'.format(removed = currentPath))
except PermissionError:
    if sys.platform == 'darwin':
        os.system('chflags nouchg {}'.format(currentPath))
        os.remove(currentPath)
    else:
        raise
except BaseException as e:
    ...
+1

Source: https://habr.com/ru/post/1693338/


All Articles