PermissionError when copying files using shutil.copyfile - python

I am a beginner in python and this is my first application.
So, basically, the application takes a folder with mp3 files in it, and reads the metadata for artist name, and then sorts the songs accordingly by copying them into newly created sub-folders named after the artist name. If there's no artist name, it would create a folder called 'unsorted' and copy files into that. I have got to the point of being able to create new folders, but the last bit which is copying the files gives me a PermissionError. Below are the code and the error I am getting.
import os
import eyed3
import shutil
# get the path to music directory
musicFolder = input('please enter the full path of your music folder : ')
correctedPath = musicFolder.replace('/', '//')
musicList = []
# list of audio file objects
for _files in os.listdir(correctedPath):
if _files.endswith('.mp3'):
musicList.append(eyed3.load(correctedPath + '//' + _files))
sortedFolder = ''
# check tag info for album artist, and sort to folders
for _audioFiles in musicList:
if _audioFiles.tag.album_artist != None:
sortedFolder = correctedPath + '//' + _audioFiles.tag.album_artist
else:
sortedFolder = correctedPath + '//' + 'Unsorted'
if not os.path.exists(sortedFolder):
os.mkdir(sortedFolder)
shutil.copyfile(_audioFiles.path, sortedFolder)
Error
PermissionError: [Errno 13] Permission denied: 'C://Users//Manu//Music//Music Test//Coldplay'
Any help is highly appreciated.
Thanks for your time.

It looks to me like you are using forward slash / where you should be using backslash .
'C://Users//Manu//Music//Music Test//Coldplay'
should be
'C:\\Users\\Manu\\Music\\Music Test\\Coldplay'
Better yet, Python has built in libraries to assist with paths: os.path and pathlib.
https://medium.com/#ageitgey/python-3-quick-tip-the-easy-way-to-deal-with-file-paths-on-windows-mac-and-linux-11a072b58d5f

shutil.copy2(src,dst) fixed it for me. I changed it from shutil.copyfile.
shutil copy functions

Related

How to make this file execute on another computer - how to have a changeable path?

I am trying to make a keylogger, it works on my computer but when i turn it into an executable it gives me an error "Python failed to execute script keylogger" I think its a path problem because its static and every computer have a diffrent directory, i am a beginner i could use some help.
files = ["log.txt", "info.txt", "clipboard.txt", "screenshot.png"]
dir_path=r"C:/Users/messa/Desktop/Python keylogger/"
##This function to take a screenshot---------------
def takess():
im = ImageGrab.grab()
im.save(dir_path+ "/" + "screenshot.png")
## i have multiple functions tell me if this is not enough .
My solution idea: I tried to check for this path if it does not exist i'll create it, after creating the directory i want to create the files in this directory, but it gives me a permission error " PermissionError: [Errno 13] Permission denied:"
extend = "\\"
dir_path="C:\\Users\\Default\\AppData\\Local"
Path(dir_path).mkdir(parents=True, exist_ok=True)
files = ["log.txt", "info.txt", "clipboard.txt", "screenshot.png"]
for file in files:
f= open(dir_path + extend + file, "w+")
f.close()
You can use pathlib module to get a stored location
import pathlib
dir_path = pathlib.Path().absolute()

Python - Paste document to each folder in directory

I have an annual file located on our netwrok that contains sub-folders based on each week of the year. I am trying to write a script that will copy a "Template" document saved on my desktop, then iterate through the annual file, and paste the Template into each weekly sub-folder.
I have a script that is generating a "PermissionError: [Errno 13] Permission denied:" though I am not sure why, and therefore not sure what to do about it.
import os
import shutil
myPath = r"""K:\PROCESS\YEAR"""
myDocument = r"""C:\Users\me.domain\OneDrive - Co Name\Desktop\Template.xlsx"""
for filename in os.listdir(myPath):
with open(os.path.join(myPath,filename)) as myFile:
copyfile(myDocument, myFile)
Error is,
PermissionError: [Errno 13] Permission denied: ‘K:\PROCESS\YEAR\WEEK 1’
# line 'with open(os.path.join(myPath,filename)) as myFile:'
I tried moving the target document to the program root and modified the script based on some sugestions as seen below.
import os
from shutil import copy2
my_doc_path = "Template.xlsx"
myPath = "K:\PROCESS\YEAR"
for directory in os.listdir(myPath):
copy2(my_doc_path, directory)
I am no longer receiving any errors; however, the target document is not being coppied to the target directory. Instead, a nondescript "file" with the target directory name is being created in the program root as seen in the image below.
What ended up working:
import os
from shutil import copy
my_doc_path = "Template.xlsx"
myPath = "K:\PROCESS\YEAR"
for directory in os.listdir(myPath):
target_directory = myPath + '\\' + directory
check_file = target_directory + '\\' + my_doc_path
if not os.path.exists(check_file):
copy(my_doc_path, target_directory)
Instead of opening a file, try to copy your file in the target folders.
from shutil import copy
my_doc_path = "/here/is/my/doc/path.xlsx"
myPath = "K:\PROCESS\YEAR"
for directory in os.listdir(myPath):
copy(my_doc_path, directory)
Or if you need also the metadata:
from shutil import copy2
my_doc_path = "/here/is/my/doc/path.xlsx"
myPath = "K:\PROCESS\YEAR"
for directory in os.listdir(myPath):
copy2(my_doc_path, directory)
Why copy/copy2 instead of copyfile? take a look at this comment
The document name needed to be appended to myPath variable. I incorrectly assumed the copy2() function was looking for the path to save the document to, I didnt realize it required the full destination path including the document itself.
Thanks for the feedback everyone, it got me pointed in the right direction.

Trouble to only move files and not directories

Trying to move files from logfile_directory to tmp_directory in blocks of 7 using random.sample.
If there are less than 7 files in the folder it will just move the remainder of the files. However when I try and move less that 7 files I get an error as the tmp_folder is trying to copy into itself.
Tried using glob.glob command but can't get that to work either. Not sure what I'm doing wrong to just move the files and not folder. Any help would be appreciated.
Running the same code on a different machine and getting the below message where as before the error message was related to copying the tmp_folder into itself. Nothing special about this file it's creating the error on so don't know why I'm now getting this.
Message=[WinError 5] Access is denied: 'c:\securelog_test\bdlog.txt'
Source=C:\Users\jarra\source\repos\archive_test\archive_test.py
StackTrace:
File "\archive_test.py", line 72, in
shutil.move(path, tmp_folder)
logfile_directory = 'c:\\securelog_test\\'
archive_folder = 'c:\\securelog_archive\\'
workfiles_folder = 'c:\\securelog_workfiles\\'
tmp_folder = 'c:\\securelog_test\\temp\\'
completed_folder = 'c:\\securelog_test\\completed\\'
#count how many files are in the log file folder
onlyfiles = [f for f in listdir(logfile_directory) if isfile(join(logfile_directory, f))]
print('-----------------')
print (len(onlyfiles))
if len(onlyfiles) > 7:
#move 7 random files to the temp folder for archiving
files = os.listdir(logfile_directory)
for fileName in random.sample(files, min(len(files), 8)):
path = os.path.join(logfile_directory, fileName)
shutil.move(path, tmp_folder)
else:
#if there are less than 7 files move them
#for file in glob.glob(logfile_directory):
# shutil.move(file, tmp_folder)
for fileName in os.listdir(logfile_directory):
path = os.path.join(logfile_directory, fileName)
shutil.move(path, tmp_folder)
Well, seems that file existed in the destination folder and couldn't write over it. Not sure why so will look into that eventually.
In order to make my life a bit easier I put the temp and completed folders into their own root folders like below and this seems to work with out any issues. Feel this is cheating a bit and would love to try and figure this out but I need to move onto other elements of the program.
logfile_directory = 'c:\\securelog\\securelog_test\\'
archive_folder = 'c:\\securelog\\securelog_archive\\'
workfiles_folder = 'c:\\securelog\\securelog_workfiles\\'
tmp_folder = 'c:\\securelog\\temp\\'
completed_folder = 'c:\\securelog\\completed\\'
check the os current directory path try to print it for each iteration you get where its getting wrong.

Copy a file with Python but not overwrite the file if it's already exists in target directory

I'm having an issue figuring out how can i implement a function to overcome my problem.
My code works fine, but the fault is that sometimes i need more than just one file.
import os
import shutil
target_dir = 'C:\DIST\WR_4.5\Test'
pass_text = 'Test End'
def check_and_copy():
log = open('C:\DIST\WR_4.5\oHistory2.log')
for line in log:
if pass_text in line:
name = '\kp.log'
else:
name = '\kf.log'
if not os.path.exists(target_dir):
os.makedirs(target_dir)
shutil.copy2('C:\DIST\WR_4.5\oHistory2.log', target_dir+name)
else:
os.chdir(target_dir)
shutil.copy2('C:\DIST\WR_4.5\oHistory2.log', target_dir+name)
What i'd like to accomplish is to be able to copy multiple instances of files with or without shutil. The filename is determined by the code itself as you can see.
Thanks for the help in advance.

Moving specific file types with Python

I know this is going to be frustratingly easy for many of you. I am just beginning to learn Python and need help with some basic file handling.
I take a lot of screenshots, which end up on my desktop (as this is the default setting). I am aware I can change the screenshot setting to save it somewhere else automatically. However, I think this program will be a good way to teach me how to sort files. I would like to use python to automatically sort through all the files on my desktop, identify those that end with .png (the default file type for screenshots), and simply move it to a folder I've named "Archive".
This is what I've got so far:
import os
import shutil
source = os.listdir('/Users/kevinconnell/Desktop/Test_Folder/')
destination = 'Archive'
for files in source:
if files.endswith('.png'):
shutil.move(source, destination)
I've played around with it plenty to no avail. In this latest version, I am encountering the following error when I run the program:
Traceback (most recent call last):
File "pngmove_2.0.py", line 23, in
shutil.move(source, destination)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 290, in move
TypeError: coercing to Unicode: need string or buffer, list found
I am under the impression I have a sort of issue with the proper convention/syntax necessary for the source and destination. However, I've thus far been unable to find much help on how to fix it. I used os.path.abspath() to determine the file path you see above.
Thanks in advance for any help in preserving my sanity.
LATEST UPDATE
I believe I am very close to getting to the bottom of this. I'm sure if I continue to play around with it I'll figure it out. Just so everyone that's been helping me is updated...
This is the current code I'm working with:
import os
import shutil
sourcepath ='/Users/kevinconnell/Desktop/'
source = os.listdir(sourcepath)
destinationpath = '/Users/kevinconnell/Desktop/'
for files in source:
if files.endswith('.png'):
shutil.move(os.path.join(sourcepath,'Test_Folder'), os.path.join(destinationpath,'Archive'))
This works for renaming my 'Test_Folder' folder to 'Archive'. However, it moves all the files in the folder, instead of moving the files that end with '.png'.
You're trying to move the whole source folder, you need to specify a file path
import os
import shutil
sourcepath='C:/Users/kevinconnell/Desktop/Test_Folder/'
sourcefiles = os.listdir(sourcepath)
destinationpath = 'C:/Users/kevinconnell/Desktop/Test_Folder/Archive'
for file in sourcefiles:
if file.endswith('.png'):
shutil.move(os.path.join(sourcepath,file), os.path.join(destinationpath,file))
Another option is using glob module, which let's you specify file mask and retrieve list of desired files.
It should be as simple as
import glob
import shutil
# I prefer to set path and mask as variables, but of course you can use values
# inside glob() and move()
source_files='/Users/kevinconnell/Desktop/Test_Folder/*.png'
target_folder='/Users/kevinconnell/Dekstop/Test_Folder/Archive'
# retrieve file list
filelist=glob.glob(source_files)
for single_file in filelist:
# move file with full paths as shutil.move() parameters
shutil.move(single_file,target_folder)
Nevertheless, if you're using glob or os.listdir, remember to set full paths for source file and target.
Based on #Gabriels answer.
I have put some effort into this as, I like to "Categorize" my file types into folders. I now use this.
I believe this is what you are looking for, this was fun to figure out
This Script:
Shows Example files to be moved until you uncomment shutil.move
Is in Python3
Was Designed On a MacOSX
Will not create folders for you, it will throw an error
Can find and move files with extension you desire
Can be used to Ignore folders
Including the destination folder, should it be nested in your search folder
Can be found in my Github Repo
Example from Terminal:
$ python organize_files.py
filetomove: /Users/jkirchoff/Desktop/Screen Shot 2018-05-15 at 12.16.21 AM.png
movingfileto: /Users/jkirchoff/Pictures/Archive/Screen Shot 2018-05-15 at 12.16.21 AM.png
Script:
I named organize_files.py
#!/usr/bin/env python3
# =============================================================================
# Created On : MAC OSX High Sierra 10.13.4 (17E199)
# Created By : Jeromie Kirchoff
# Created Date: Mon May 14 21:46:03 PDT 2018
# =============================================================================
# Answer for: https://stackoverflow.com/a/23561726/1896134 PNG Archive
# NOTE: THIS WILL NOT CREATE THE DESTINATION FOLDER(S)
# =============================================================================
import os
import shutil
file_extensn = '.png'
mac_username = 'jkirchoff'
search_dir = '/Users/' + mac_username + '/Desktop/'
target_foldr = '/Users/' + mac_username + '/Pictures/Archive/'
ignore_fldrs = [target_foldr,
'/Users/' + mac_username + '/Documents/',
'/Users/' + mac_username + '/AnotherFolder/'
]
for subdir, dirs, files in os.walk(search_dir):
for file in files:
if subdir not in ignore_fldrs and file.endswith(file_extensn):
# print('I would Move this file: ' + str(subdir) + str(file)
# # + "\n To this folder:" + str(target_foldr) + str(file)
# )
filetomove = (str(subdir) + str(file))
movingfileto = (str(target_foldr) + str(file))
print("filetomove: " + str(filetomove))
print("movingfileto: " + str(movingfileto))
# =================================================================
# IF YOU ARE HAPPY WITH THE RESULTS
# UNCOMMENT THE SHUTIL TO MOVE THE FILES
# =================================================================
# shutil.move(filetomove, movingfileto)
pass
elif file.endswith(file_extensn):
# print('Theres no need to move these files: '
# + str(subdir) + str(file))
pass
else:
# print('Theres no need to move these files either: '
# + str(subdir) + str(file))
pass
import os
import shutil
Folder_Target = input("Path Target which Contain The File Need To Move it: ")
File_Extension = input("What Is The File Extension ? [For Example >> pdf , txt , exe , ...etc] : ")
Folder_Path = input("Path To Move in it : ")
Transformes_Loges = input("Path To Send Logs Of Operation in : ")
x=0
file_logs=open(Transformes_Loges+"\\Logs.txt",mode="a+")
for folder, sub_folder, file in os.walk(Folder_Target):
for sub_folder in file:
if os.path.join(folder, sub_folder)[-3:]==File_Extension:
path= os.path.join(folder, sub_folder)
file_logs.write(path+" ===================== Was Moved to ========================>> "+Folder_Path )
file_logs.write("\n")
shutil.move(path, Folder_Path)
x+=1
file_logs.close()
print("["+str(x)+"]"+"File Transformed")

Categories