1

I am puzzled. My Python script has two parts. It's very simple.

Part-1: Makes a new folder based on date and time. Then moves all the files into that folder. This happens once a day controlled by launchd.
Part-2: It deletes the directories older than 10 days.

What I found with my new computer or OS (Ventura 13.0), when the script is not in Downloads folder, first part of the code executes just fine, but second part fails (the part deleting old directories). However, when I put the second part of my script in the

Downloads folder, it executes fine (i.e. deleting the old directories).

I am wondering if this is an MacOS permission issue. Something that allows me to create folders but not delete them when my script is run from an outside folder (outside of Downloads folder). If so, how do I solve it.

Entire code:

from datetime import datetime, date
from time import sleep
import os, shutil, pathlib

path = "/Users/user/Downloads/" #get the path to target directory
#get all the files into a list.
names = [name for name in os.listdir(path) if os.path.isfile(os.path.join(path, name))] 

#select regular files, i.e. ignore hidden files and python files
regfiles = [f for f in names if not f.startswith('.') and f in names if not f.endswith('.py')]


#Now, lets grab the file extension os that we can label our new director properly
extensions = []
for item in regfiles:
    extensions.append(pathlib.Path(item).suffix)

uniqExtensions = set(extensions)
uniqExtensions =''.join(uniqExtensions)


#get time function to name new directory
now  = datetime.now()
year = now.strftime("%Y")
month= now.strftime("%m")
day  = now.strftime("%d")
time = now.strftime("%H%M%S")
dir_name =(str(year)+str(month)+str(day)+"."+str(time))
dir_name = path + dir_name + uniqExtensions

myFilesWithFullPath=[]
for item in regfiles:
    myFilesWithFullPath.append(path+item)

os.mkdir(dir_name)
for f in myFilesWithFullPath:
    shutil.move(f, dir_name)

# #remove empty directories by a system call
#os.system("find %s -type d -empty -delete"%(path))
#------------------------
today = date.today()
names = os.listdir(path)
for item in names:
    if os.path.isdir(item):
        if not item.startswith('.'): 
            dirdate = date.fromtimestamp(os.path.getmtime(item))
            #print((today - dirdate).days)
            if ((today - dirdate).days) > 10:
                shutil.rmtree(item)

The part of the code only executes when the script is in Downloads folder:

#------------------------
today = date.today()
names = os.listdir(path)
for item in names:
    if os.path.isdir(item):
        if not item.startswith('.'): 
            dirdate = date.fromtimestamp(os.path.getmtime(item))
            #print((today - dirdate).days)
            if ((today - dirdate).days) > 10:
                shutil.rmtree(item)

Update:

Here is how I call the the Python script from .plist file. And, when I run my Python script for testing from Terminal I use:

$ python3 organize-downloads-folder.py

for testing.

</array> 
    <array>
        <string>/Users/user-x/opt/miniconda3/bin/python</string>
        <string>./Users/user-x/scripts/organize-downloads-folder.py</string>
    </array>
8
  • How are you kicking this off in launchd? As a LaunchAgent, LaunchDameon? More specifically, what user is defined to run the script?
    – Allan
    Jan 2 at 19:50
  • Let's ignore about launchd. I have the problem even I run the Python script from terminal. When I have editing privilege again, I will remove mention of launchd as it's irrelevant for my questions. I test the script as $ python3 myscript.py from the terminal.
    – Supertech
    Jan 2 at 19:53
  • launchd matters because permissions depend on the user running the process kicked off by launchd
    – Allan
    Jan 2 at 19:57
  • My launchd script is located in the LaunchAgents folder.
    – Supertech
    Jan 2 at 20:04
  • 1
    Look at you path in the second array entry of the last code block. It starts with a period (./Users/user-x/…). That means current directory/Users/user-x/…. I doubt that directory exists anywhere but from the root dir. Delete the period and it should work.
    – Allan
    Jan 2 at 20:23

1 Answer 1

1

It turned out to be that issue was in the Python code. I was not properly writing the full path to the directories in the Downloads folder. Here is the functional code after updating the second part of the script.

from datetime import date, datetime, timedelta
from time import sleep
import os, shutil, pathlib


path = "/Users/user/Downloads/" #get the path to target directory
#get all the files into a list.
names = [name for name in os.listdir(path) if os.path.isfile(os.path.join(path, name))] 

#select regular files, i.e. ignore hidden files and python files
regfiles = [f for f in names if not f.startswith('.') and f in names if not f.endswith('.py')]

#Now, lets grab the file extension os that we can label our new director properly
extensions = []
for item in regfiles:
    extensions.append(pathlib.Path(item).suffix)

uniqExtensions = set(extensions)
uniqExtensions =''.join(uniqExtensions)

#get time function to make new directory
now  = datetime.now()
year = now.strftime("%Y")
month= now.strftime("%m")
day  = now.strftime("%d")
time = now.strftime("%H%M%S")
dir_name =(str(year)+str(month)+str(day)+"."+str(time))
dir_name = path + dir_name + uniqExtensions
print(dir_name) #print on the terminal

myFilesWithFullPath=[]
for item in regfiles:
    myFilesWithFullPath.append(path+item)

# [print(x) for x in myFilesWithFullPath] #debugging
os.mkdir(dir_name)
for f in myFilesWithFullPath:
    shutil.move(f, dir_name)
    print(f)
#------------------------------
curret_time = datetime.now()
names = os.listdir(path)
for name in names:
    if os.path.isdir(os.path.join(path,name)) and not name.startswith('.'):
        mydir = (os.path.join(path,name))
        stat = os.stat(mydir)
        creation_time = datetime.fromtimestamp(stat.st_birthtime)
        dir_age = curret_time - creation_time       
        if dir_age > timedelta(4):
            #print("--remove--", mydir)
            shutil.rmtree(mydir)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .