desktop_cleanup.py

#!/usr/bin/python3
# ==============================================================
# Cleanup The Window's Desktop (Directory)
# remove unwanted link/shortcut entries
# ==============================================================
# This program is designed for the Windows OS. Unix/Linux OS
# will require some modifications of this code.
#   a. Windows has shortcuts
#   b. Unix/Linux have soft (symbolic) links and
#      hard (inode) links
# ==============================================================
#
# How to use this program:
#
# 1. Run this program with TESTMODE set to TRUE. In this
#    mode it will do everything except actually delete any
#    files/links/shortcuts.
#
# 2. Examining the output messages. Verify the program will
#    do exactly what you expecte.
#
#    You might want to un-comment the print statement
#    in the "remove_directory_entries" function to display
#    more information.
#
# 3. When you are satisfied with the test results, set
#    TESTMODE to FALSE and run this program. This will
#    delete files/links/shortcuts.
#
# 4. Be sure to set TESTMODE back to TRUE for the next time.
#
# ==============================================================
# code example for future changes
# filename_regx = []
# filename_regx.append(re.compile(r'---\.html$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.csv$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.png$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.txt$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.bat$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.php$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.py$',re.IGNORECASE))
# filename_regx.append(re.compile(r'\.pl$',re.IGNORECASE))
# filename_regx.append(re.compile(r'^aaa',re.IGNORECASE))
#     if re.search(regx,filename): do-something
# ==============================================================

import re
import os
import sys

DIRECTORY   = 'C:/Users/Tom/Desktop'

TESTMODE    = True

# ---- DO NOT REMOVE THESE ENTRIES FROM THE DIRECTORY.
# ---- THEY ARE PERMANENT DIRECTORY ENTRIES.
# ---- Note: This list may need to be modified
# ----       from time-to-time.
KEEP_ENTRIES  = [
  'AIMP.lnk', 'calc.lnk', 'Command Prompt.lnk', 'D.lnk',
  'eleanor_dunn_hours.txt.lnk', 'File Explorer.lnk',
  'FileZilla.lnk', 'hodgepodge.lnk', 'house-stuff.lnk',
  'IDLE.lnk', 'jerusalem_artichoke.txt', 'LibreOffice.lnk',
  'LibreWolf.lnk', 'lollipop.lnk', 'music.lnk', 'Notepad.lnk',
  'Paint.lnk', 'pcc.lnk', 'pictures.lnk',
  'programming-projects.lnk', 'putty.exe.lnk',
  'solutions.zip', 'streaming.txt.lnk', 'Tom-Stuff.lnk',
  'travel.lnk', 'WEX.lnk', 'when-i-am-gone.lnk',
  'XAMPP Control Panel.lnk', 'xmas.lnk', 'Zoom Workplace.lnk' ]

# --------------------------------------------------------------
# ---- get a list of directory entries
# ----
# ---- Notes: selected entries are saved in a list and
# ----        returned for further processing
# --------------------------------------------------------------

def get_directory_entries(
                directory:str,
                verbose:bool=False) -> tuple[int,int,list]:

    entry_count = 0
    saved_count = 0

    # --- directory path/name must end in a '/'

    if re.search(r'\/$',directory):
        directory = directory + '/'

    # ---- get a list of all of the entries in a directory

    entries = os.listdir(directory)

    # ---- save selected directory entries in a list

    saved_list = []

    for entry in entries:

        entry_count += 1

        # ---- skip hidden entries (they start with '.')

        if re.search(r'^\.',entry):
            if verbose: print(f'skipping {entry}')
            continue

        # ---- skip directory entries

        file_spec = os.path.join(directory,entry)

        if os.path.isdir(file_spec):
            if verbose: print(f'skipping {entry}')
            continue

        # ---- skip specific entries

        if entry in KEEP_ENTRIES:
            if verbose: print(f'skipping {entry}')
            continue

        # ---- only save window shortcut entries

        if re.search(r'.*lnk$',entry,re.IGNORECASE):
            if verbose: print(f'saving   {entry}')
            saved_list.append(entry)
            saved_count += 1
            continue

        # ---- skip entry

        if verbose: print(f'skipping {entry}')

    # ---- return list of saved-for-further-processing entries

    return (entry_count,saved_count,saved_list)

# --------------------------------------------------------------
# ---- remove directory entries
# --------------------------------------------------------------

def remove_directory_entries(
                directory:str,
                entry_list:list,
                verbose:bool=False) -> tuple[int,list]:

    removed_list  = []
    removed_count = 0

    if verbose: print()

    # --- directory path/name must end in a '/'

    if re.search(r'\/$',directory):
        directory = directory + '/'

    # ---- remove entries in the list

    for entry in entry_list:

        file_spec = os.path.join(directory,entry)

        if not TESTMODE: os.remove(file_spec)

        removed_count += 1

        removed_list.append(entry)

        ##print(f'removing {entry}')

    # ---- return list of removed entries

    return (removed_count,removed_list)

# --------------------------------------------------------------
# ---- main
# --------------------------------------------------------------

if __name__ == '__main__':

    print()
    print(f'directory    : {DIRECTORY}')
    print(f'test mode    : {TESTMODE}')

    # ---- does the directory exists?

    if not os.path.isdir(DIRECTORY):
        print()
        print('No search/process directory found')
        print()
        sys.exit()

    # ---- get a list of directory entries

    entry_count,saved_count,saved_list = \
                        get_directory_entries(DIRECTORY)

    print(f'entry   count: {entry_count}')
    print(f'saved   count: {saved_count}')

    # ---- remove a list of directory entries

    removed_count,removed_list = \
            remove_directory_entries(DIRECTORY, saved_list)

    print(f'removed count: {removed_count}')

    # --- display the removed entries

    display_removed_entries = False
    if display_removed_entries and removed_count > 0:
        print()
        for r in removed_list:
            print(f'removed  {r}')

    print()