Is it possible to make rules for file manager / Python - python

I want to ask is it possible to make a rules for file managing program. For instance, if i want to move certain file in Image folder to move only .png and .img files. How i should declare rule in the configuration file that program would understand? If you would need I would my code gladly upload it. Which libraries i would need to use or give certain examples? Thank you in advance!
from tkinter import *
from tkinter import filedialog
import easygui
import shutil
import os
from tkinter import filedialog
from tkinter import messagebox as mb
from pathlib import Path
import logging
from datetime import date
import configparser
import configdot
def open_window():
read=easygui.fileopenbox()
return read
#logging config
if Path('app.log').is_file():
print ("Log file already exist")
else:
logging.basicConfig(filename='app.log', filemode="w", format='%(name)s - %(levelname)s - %(message)s ')
print ("Log file doesn't exist, so new one was created")
LOG_for="%(asctime)s, %(message)s"
logger=logging.getLogger()
logger.setLevel(logging.DEBUG)
# move file function
def move_file():
filename = filedialog.askopenfilename(initialdir = config.select.dir,
title = config.select.ttl,
filetypes = config.select.ft)
destination =filedialog.askdirectory()
dest = os.path.join(destination,filename)
if(source==dest):
mb.showinfo('confirmation', "Source and destination are the same, therefore file will be moved to Home catalog")
newdestination = Path("/home/adminas")
shutil.move(source, newdestination)
logging.shutdown()
logging.basicConfig(filename='app.log', filemode="a", format=LOG_for)
logging.info('File *' + filename + '* was moved to new destination: ' + newdestination)
else:
shutil.move(source, destination)
mb.showinfo('confirmation', "File Moved !")
#current_time()
logging.basicConfig(filename='app.log', filemode="a", format=LOG_for)
logging.info('File *' + filename + '* was moved to new destination: ' + destination)
# Create the root window
window = Tk()

It sounds like you want to move only files of a specific type (e.g. .png or .img). You can do this based on the file name itself using endswith:
if source.endswith('.png'):
shutil.move(source, newdestination)
You can see an example in this answer Converting images to csv file in python where the function walks through a directory and creates a list of files that all share the same file extension.
Note that this code only checks the file extension, not the actual file itself.
Now, say you only want to apply this rule to a folder called "Images", then you can still use string manipulation. You might use contains:
if source.contains("Images"):
# do something
Alternatively, if you know your file path might contain the word "Images" more than once, you can use os.path.split(path) to split the path into "path" and "file", and then again on the resulting head to split it into "path" and last folder. Compare the resulting tail to Images:
h, t = os.path.split(source)
h2, t2 = os.path.split(h)
if t2.contains("Images"):
#do something
There are other ways to do this using the os.path functions and you will want to investigate these.

Related

Is there a simpler function or one liner to check if folder exists if not create it and paste a specific file into it?

I am aiming to create a function that does the following:
Declare a path with a file, not just a folder. e.g. 'C:/Users/Lampard/Desktop/Folder1/File.py'
Create a folder in same folder as the declared file path - Calling it 'Archive'
Cut the file and paste it into the new folder just created.
If the folder 'Archive' already exists - then simply cut and paste the file into there
I have spent approx. 15-20min going through these:
https://www.programiz.com/python-programming/directory
Join all except last x in list
https://docs.python.org/3/library/pathlib.html#operators
And here is what I got to:
import os
from pathlib import Path, PurePath
from shutil import copy
#This path will change every time - just trying to get function right first
path = 'C:/Users/Lampard/Desktop/Folder1/File.py'
#Used to allow suffix function
p = PurePath(path)
#Check if directory is a file not a folder
if not p.suffix:
print("Not an extension")
#If it is a file
else:
#Create new folder before last file
#Change working directory
split = path.split('/')
new_directory = '/'.join(split[:-1])
apply_new_directory = os.chdir(new_directory)
#If folder does not exist create it
try:
os.mkdir('Archive')#Create new folder
#If not, continue process to copy file and paste it into Archive
except FileExistsError:
copy(path, new_directory + '/Archive/' + split[-1])
Is this code okay? - does anyone know a simpler method?
Locate folder/file in path
print [name for name in os.listdir(".") if os.path.isdir(name)]
Create path
import os
# define the name of the directory to be created
path = "/tmp/year"
try:
os.mkdir(path)
except OSError:
print ("Creation of the directory %s failed" % path)
else:
print ("Successfully created the directory %s " % path)
To move and cut files you can use this library
As you're already using pathlib, there's no need to use shutil:
from pathlib import Path
path = 'C:/Users/Lampard/Desktop/Folder1/File.py' # or whatever
p = Path(path)
target = Path(p.with_name('Archive')) # replace the filename with 'Archive'
target.mkdir() # create target directory
p.rename(target.joinpath(p.name)) # move the file to the target directory
Feel free to add appriopriate try…except statements to handle any errors.
Update: you might find this version more readable:
target = p.parent / 'Archive'
target.mkdir()
p.rename(target / p.name)
This is an example of overloading / operator.

Is this the shortest, most efficient way to write a program to move my pdf files into a new folder?

New to coding, reading some books and trying to practice. Wrote a program in python3.7 to search through a directory, find all the pdf files and move them to a new folder called 'Reading Materials'.
How could I improve on this code e.g a shorter, more concise and/or efficient script in python?
import os, re, shutil
os.chdir(r'C:\\Users\\Luke\\Documents\\coding\\python\\') #set cwd to the where I want program to run
#create regex to identify pdf files
PDFregex = re.compile(r'''^(.*?) # all text before the file extension
\.{1} #start of file extension
(pdf)$ #ending in pdf''', re.VERBOSE)
Newdir = os.mkdir('Reading Material') #make new directory for files
NewdirPath = os.path.abspath('Reading Material')
print('new directory made at : '+NewdirPath)
#search through directory for files that contain .pdf extension using regex object
for pdf in os.listdir('.'):
mo = PDFregex.search(pdf)
if mo == None: #no pdf's found by regex search
continue #bypass loop
else:
originalLoc = os.path.join(os.path.abspath('.'), pdf) #original file location
newLoc = shutil.move(originalLoc, os.path.join(NewdirPath, pdf)) #move pdf to new folder
print('Moving file "%s" moved to "%s"...' %(pdf, newLoc)) #say what's moving
os.listdir(NewdirPath)
Regexp is overkilled here. os module has various method to help you extract informations about files.
You can use splitext method in os module to find the extension.
Something like this should work :
import os
import shutil
old_dir = 'C:\\Users\\Luke\\Documents\\coding\\python\\'
new_dir = 'Reading Material'
# You should always use underscore_notations to name variables instead of CamelCase (use for ClassNames) see https://www.python.org/dev/peps/pep-0008/
os.makedirs(new_dir, exist_ok=True)
for file_path in os.listdir(old_dir):
if os.path.splitext(file_path)[1] == '.pdf':
shutil.move(file_path, '{0}\\{1}'.format(new_dir, os.path.basename(file_path)))

How to move from one directory to another and delete only '.html' files in python?

I attended an interview and they asked me to write a script to move from one directory to another and delete only the .html files.
Now I tried to do this at first using os.remove() . Following is the code:
def rm_files():
import os
from os import path
folder='J:\\Test\\'
for files in os.listdir(folder):
file_path=path.join(folder,files)
os.remove(file_path)
The problem I am facing here is that I cannot figure out how to delete only .html files in my directory
Then I tried using glob. Following is the code:
def rm_files1():
import os
import glob
files=glob.glob('J:\\Test\\*.html')
for f in files:
os.remove(f)
Using glob I can delete the .html files but still I cannot figure out how to implement the logic of moving from one directory to another.
And along with that can someone please help me figure out how to delete a specific file type using os.remove() ?
Thank you.
Either of these methods should work. For the first way, you could just string.endswith(suffix) like so:
def rm_files():
import os
from os import path
folder='J:\\Test\\'
for files in os.listdir(folder):
file_path=path.join(folder,files)
if file_path.endswith(".html"):
os.remove(file_path)
Or if you prefer glob, moving directories is fairly straightforward: os.chdir(path) like this:
def rm_files1():
import os
os.chdir('J:\\Test')
import glob
files=glob.glob('J:\\Test\\*.html')
for f in files:
os.remove(f)
Though it seems unnecessary since glob is taking an absolute path anyway.
Your problem can be described in the following steps.
move to specific directory. This can be done using os.chdir()
grab list of all *.html files. Use glob.glob('*.html')
remove the files. use os.remove()
Putting it all together:
import os
import glob
import sys
def remove_html_files(path_name):
# move to desired path, if it exists
if os.path.exists(path_name):
os.chdir(path_name)
else:
print('invalid path')
sys.exit(1)
# grab list of all html files in current directory
file_list = glob.glob('*.html')
#delete files
for f in file_list:
os.remove(f)
#output messaage
print('deleted '+ str(len(file_list))+' files in folder' + path_name)
# call the function
remove_html_files(path_name)
To remove all html files in a directory with os.remove() you can do like this using endswith() function
import sys
import os
from os import listdir
directory = "J:\\Test\\"
test = os.listdir( directory )
for item in test:
if item.endswith(".html"):
os.remove( os.path.join( directory, item ) )

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")

How to extract a file within a folder within a zip?

I need to extract a file called Preview.pdf from a folder called QuickLooks inside of a zip file.
Right now my code looks a little like this:
with ZipFile(newName, 'r') as newName:
newName.extract(\QuickLooks\Preview.pdf)
newName.close()
(In this case, newName has been set equal to the full path to the zip).
It's important to note that the backslash is correct in this case because I'm on Windows.
The code doesn't work; here's the error it gives:
Traceback (most recent call last):
File "C:\Users\Asit\Documents\Evam\Python_Scripts\pageszip.py", line 18, in <module>
ZF.extract("""QuickLooks\Preview.pdf""")
File "C:\Python33\lib\zipfile.py", line 1019, in extract
member = self.getinfo(member)
File "C:\Python33\lib\zipfile.py", line 905, in getinfo
'There is no item named %r in the archive' % name)
KeyError: "There is no item named 'QuickLook/Preview.pdf' in the archive"
I'm running the Python script from inside Notepad++, and taking the output from its console.
How can I accomplish this?
Alternatively, how could I extract the whole QuickLooks folder, move out Preview.pdf, and then delete the folder and the rest of it's contents?
Just for context, here's the rest of the script. It's a script to get a PDF of a .pages file. I know there are bonified converters out there; I'm just doing this as an excercise with some sort of real-world application.
import os.path
import zipfile
from zipfile import *
import sys
file = raw_input('Enter the full path to the .pages file in question. Please note that file and directory names cannot contain any spaces.')
dir = os.path.abspath(os.path.join(file, os.pardir))
fileName, fileExtension = os.path.splitext(file)
if fileExtension == ".pages":
os.chdir(dir)
print (dir)
fileExtension = ".zip"
os.rename (file, fileName + ".zip")
newName = fileName + ".zip" #for debugging purposes
print (newName) #for debugging purposes
with ZipFile(newName, 'w') as ZF:
print("I'm about to list names!")
print(ZF.namelist()) #for debugging purposes
ZF.extract("QuickLook/Preview.pdf")
os.rename('Preview.pdf', fileName + '.pdf')
finalPDF = fileName + ".pdf"
print ("Check out the PDF! It's located at" + dir + finalPDF + ".")
else:
print ("Sorry, this is not a valid .pages file.")
sys.exit
I'm not sure if the import of Zipfile is redundant; I read on another SO post that it was better to use from zipfile import * than import zipfile. I wasn't sure, so I used both. =)
EDIT: I've changed the code to reflect the changes suggested by Blckknght.
Here's something that seems to work. There were several issues with your code. As I mentioned in a comment, the zipfile must be opened with mode 'r' in order to read it. Another is that zip archive member names always use forward slash / characters in their path names as separators (see section 4.4.17.1 of the PKZIP Application Note). It's important to be aware that there's no way to extract a nested archive member to a different subdirectory with Python's currentzipfilemodule. You can control the root directory, but nothing below it (i.e. any subfolders within the zip).
Lastly, since it's not necessary to rename the .pages file to .zip — the filename you passZipFile() can have any extension — I removed all that from the code. However, to overcome the limitation on extracting members to a different subdirectory, I had to add code to first extract the target member to a temporary directory, and then copy that to the final destination. Afterwards, of course, this temporary folder needs to deleted. So I'm not sure the net result is much simpler...
import os.path
import shutil
import sys
import tempfile
from zipfile import ZipFile
PREVIEW_PATH = 'QuickLooks/Preview.pdf' # archive member path
pages_file = input('Enter the path to the .pages file in question: ')
#pages_file = r'C:\Stack Overflow\extract_test.pages' # hardcode for testing
pages_file = os.path.abspath(pages_file)
filename, file_extension = os.path.splitext(pages_file)
if file_extension == ".pages":
tempdir = tempfile.gettempdir()
temp_filename = os.path.join(tempdir, PREVIEW_PATH)
with ZipFile(pages_file, 'r') as zipfile:
zipfile.extract(PREVIEW_PATH, tempdir)
if not os.path.isfile(temp_filename): # extract failure?
sys.exit('unable to extract {} from {}'.format(PREVIEW_PATH, pages_file))
final_PDF = filename + '.pdf'
shutil.copy2(temp_filename, final_PDF) # copy and rename extracted file
# delete the temporary subdirectory created (along with pdf file in it)
shutil.rmtree(os.path.join(tempdir, os.path.split(PREVIEW_PATH)[0]))
print('Check out the PDF! It\'s located at "{}".'.format(final_PDF))
#view_file(final_PDF) # see Bonus below
else:
sys.exit('Sorry, that isn\'t a .pages file.')
Bonus: If you'd like to actually view the final pdf file from the script, you can add the following function and use it on the final pdf created (assuming you have a PDF viewer application installed on your system):
import subprocess
def view_file(filepath):
subprocess.Popen(filepath, shell=True).wait()

Categories