Python: copy file tree to a text file - python-3.x

I'm trying to create a text file with a tree of all files / dirs from a place that I choose using os.chdir(). My approach is to print the tree and to save all prints to the text file. The problem is that it doesn't copy the printed tree and the file is blank.
What am I doing wrong?
And is there a way to write this kind of data to the file without to actually print it?
My code:
import os
import sys
f = open("tree.txt", "w")
os.chdir("c:\\Users\Daniel\Desktop")
sys.stdout = f
os.system("tree /f")
f.close()
Edit
I was able to get the file tree from the clipboard after executing the command, however it gives me and eror when it tried to write to the txt file.
code:
import os
import tkinter
with open("tree.txt", "w") as f:
os.system("tree /f |clip")
root = tkinter.Tk()
tree = root.clipboard_get()
print(tree)
f.write(tree)
eror:
Traceback (most recent call last):
File "c:\Users\Daniel\Desktop\Tick\code_test\files.py", line 9, in <module>
f.write(tree)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python38-32\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2502' in position 80: character maps to <undefined>
solution
So I found the problem, I needed to use codec to be able write unicode to the text file. Now it works very well
code:
import os
import tkinter
import codecs
with codecs.open("tree.txt", "w", "utf8") as f:
os.chdir("c:\\Users")
os.system("tree /f |clip")
root = tkinter.Tk()
tree = root.clipboard_get()
f.write(tree)

Method check_output from subprocess module can help you to catch program output:
import subprocess
f = open("tree.txt", "wb")
tree_output = subprocess.check_output('tree /f', shell=True, cwd=r'c:\Users\Daniel\Desktop')
f.write(tree_output)
f.close()
Or with context manager:
import subprocess
with open("tree.txt", "wb") as f:
f.write(subprocess.check_output('tree /f', shell=True, cwd=r'c:\Users\Daniel\Desktop'))
Option wb is required because check_output returns bytes not a str. If you want to process output like a string - call tree_output.decode() first.

Related

How to randomly copy the contents of a text document to my clipboard

This is my original question
The following script copies the text in /home/my_files/document1.txt to my clipboard.
import pyperclip
path = '/home/my_files/document1.txt'
The_text_of_the_file_that_will_be_copied = open(path, 'r').read()
pyperclip.copy(The_text_of_the_file_that_will_be_copied)
Let's say /home/my_files/ contains the following five documents:
/home/my_files/document1.txt
/home/my_files/document2.txt
/home/my_files/document3.txt
/home/my_files/image1.jpg
/home/my_files/image2.png
I would like to create a script to randomly copy the contents of one of the three text documents in /home/my_files/ to my clipboard.
Of course the following script does not work but it shows some of the modules I've been experimenting with.
import glob,random,pyperclip
pattern = "*.txt"
path = random.choice((glob.glob(pattern))("/home/my_files/"))
The_text_of_the_file_that_will_be_copied = open(path, 'r').read()
pyperclip.copy(The_text_of_the_file_that_will_be_copied)
Do you have any relevant suggestions for me?
I added the subsequent content to my original question above
When I tried the following solution which #Jacob Lee created...
import glob
import random
import pyperclip
files = [os.path.abspath(f) for f in glob.glob("./home/my_files")]
path = random.choice(files)
with open(path) as f:
pyperclip.copy(f.read())
I received the following error message...
Traceback (most recent call last):
File "abc.py", line 3, in <module>
path = random.choice(glob.glob(pattern))
File "/usr/lib/python3.8/random.py", line 290, in choice
raise IndexError('Cannot choose from an empty sequence') from None
IndexError: Cannot choose from an empty sequence
Someone else suggested the following script to me...
import glob,random,pyperclip
pattern = "/home/my_files/*.txt"
path = random.choice(glob.glob(pattern))
print("copying contents of ", path)
The_text_of_the_file_that_will_be_copied = open(path, 'r').read()
pyperclip.copy(The_text_of_the_file_that_will_be_copied)
But that script doesn't work either. I received the following error when I ran that script...
Traceback (most recent call last):
File "abc.py", line 3, in <module>
path = random.choice(glob.glob(pattern))
File "/usr/lib/python3.8/random.py", line 290, in choice
raise IndexError('Cannot choose from an empty sequence') from None
IndexError: Cannot choose from an empty sequence
I am confused.
The following successfully copies the entire contents of a random text file in /home/my_files/ to my clipboard
import glob,random,pyperclip
pattern = "/home/my_files/*.txt"
path = random.choice(glob.glob(pattern))
print("copying contents of ", path)
The_text_of_the_file_that_will_be_copied = open(path, 'r').read()
pyperclip.copy(The_text_of_the_file_that_will_be_copied)
Thanks to #Asocia
Thanks to #Asocia for insisting that the script above works correctly. I don't know what I had been doing wrong, but I must have been doing something wrong when I indicated the script above did not work properly.
You're code raises a TypeError: 'list' object is not callable exception when you try to assign path, in this line:
path = random.choice((glob.glob(pattern))("/home/my_files"))
glob.glob() returns a list (possibly empty). (Also, you put the glob.glob() call inside redundant parentheses.) Then, you try to call glob.glob()("/home/my_files/") (in essence, [...](), raising the TypeError exception.
import glob
import random
import pyperclip
files = [os.path.abspath(f) for f in glob.glob("./home/my_files/*.txt")]
path = random.choice(files)
with open(path) as f:
pyperclip.copy(f.read())

Running "replace contractions" across all text files in same directory and output to multiple text files in another directory

I am a beginner user of Python.
I am writing a Python script using "replace contractions" to replace contractions in all text files in the same directory with the expanded words, and then outputting the replaced files to another directory.
The code looks like the following at present:
import re, string, unicodedata
import nltk
import contractions
import inflect
import os
txt_files = [f for f in os.listdir('./test') if f.endswith('.txt')]
fd = open(txt_files)
with open(txt_files)as fd:
fd.method
fd.close()
def replace_contractions(text):
"""Replace contractions in string of text"""
return contractions.fix(text)
output_strings = map(replace_contractions, txt_files)
output_content = "".join(sorted(output_strings)) # sort join the output strings without separators
# write to file
with open(folder_path + output_filename, 'wt') as outfile:
outfile.write(output_content)
The error which I have received is:
"Traceback (most recent call last):
File "C:\Users\User\Desktop\Text Preprocessing.py", line 9, in <module>
fd = open(txt_files)
TypeError: invalid file: ['1.txt', '2.txt']"
Can anyone advise me on resolving the error? Thank you!
I have now edited my code to the following:
import re, string, unicodedata
import nltk
import contractions
import inflect
import os
txt_files = [f for f in os.listdir('./test') if f.endswith('.txt')]
import glob
for each_file in glob.glob("arc\.\d+\.txt"):
print(each_file)
def replace_contractions(text):
"""Replace contractions in string of text"""
return contractions.fix(text)
output_strings = map(replace_contractions, txt_files)
output_content = "".join(sorted(output_strings)) # sort join the output strings without separators
# write to file
folder_path = 'C:\\Users\\User\\Desktop\\test1\\'
output_filename = os.path.join(folder_path, '.txt')
with open(output_filename, 'wt') as outfile:
outfile.write(output_content)
There is no error. But I have 2 output files. The first is a text file with the string "1.txt2.txt" inside the text file and the second file has a filename as an underscore and is without any extension. I am not getting the desired output in the txt files, i.e. to expand the contractions in the text inside the txt files. Can anyone help out?

looping over images in a directory

I have images in the same directory with a python file, i am trying to loop over the images and convert them into base64 but am getting this error.
Am using Ubuntu 14.0.4
Traceback (most recent call last):
File "convert_to_base64.py", line 33, in <module>
print(main())
File "convert_to_base64.py", line 26, in main
convert_to_base64()
File "convert_to_base64.py", line 19, in convert_to_base64
with open("*.jpg", "rb") as f:
IOError: [Errno 2] No such file or directory: '*.jpg'
Here is my python code
# -*- coding: utf-8 -*-
import os
import sys
import xlrd
import base64
import urllib
from datetime import datetime
reload(sys) # to re-enable sys.setdefaultencoding()
sys.setdefaultencoding('utf-8')
def convert_to_base64():
"""
Read all jpg images in a folder,
and print them in base64
"""
with open("*.jpg", "rb") as f:
data = base64.b64decode(f.read())
print data
def main():
start_datetime = datetime.now()
convert_to_base64()
end_datetime = datetime.now()
print '------------------------------------------------------'
print 'Script started : {}'.format(start_datetime)
print 'Script finished: {}'.format(end_datetime)
if __name__ == '__main__':
print(main())
print('Done')
someone help me figure out what am doing wrong.
Thanks
This is how I looped for images in a directory:
import os
pictures = []
for file in os.listdir("pictures"):
if file[-3:].lower() in ["png"]:
pictures.append(file)
Please refer to Python documentation https://docs.python.org/2/tutorial/inputoutput.html for more info on open() function:
open() returns a file object, and is most commonly used with two arguments: open(filename, mode).

Writing pdf with pypdf2 gives error

I'm trying to write a simple script to merge two PDFs but have run into an issue when trying to save the output to disk. My code is
from PyPDF2 import PdfFileWriter, PdfFileReader
import tkinter as tk
from tkinter import filedialog
### Prompt the user for the 2 files to use via GUI ###
root = tk.Tk()
root.update()
file_path1 = tk.filedialog.askopenfilename(
filetypes=[("PDF files", "*.pdf")],
)
file_path2 = tk.filedialog.askopenfilename(
filetypes=[("PDF files", "*.pdf")],
)
###Function to combine PDFs###
output = PdfFileWriter()
def append_pdf_2_output(file_handler):
for page in range(file_handler.numPages):
output.addPage(file_handler.getPage(page))
#Actually combine the 2 PDFs###
append_pdf_2_output(PdfFileReader(open(file_path1, "rb")))
append_pdf_2_output(PdfFileReader(open(file_path2, "rb")))
###Prompt the user for the file save###
output_name = tk.filedialog.asksaveasfile(
defaultextension='pdf')
###Write the output to disk###
output.write(output_name)
output.close
The problem is that I get an error of
UserWarning: File to write to is not in binary mode. It may not be written to correctly. [pdf.py:453] Traceback (most recent call last): File "Combine2Pdfs.py", line 44, in output.write(output_name) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/pytho‌​n3.5/site-packages/P‌​yPDF2/pdf.py", line 487, in write stream.write(self.header + b("\n")) TypeError: write() argument must be str, not bytes
Where have I gone wrong?
I got it by adding mode = 'wb' to tk.filedialog.asksaveasfile. Now it's
output_name = tk.filedialog.asksaveasfile(
mode = 'wb',
defaultextension='pdf')
output.write(output_name)
Try to use tk.filedialog.asksaveasfilename instead of tk.filedialog.asksaveasfile. You just want the filename, not the file handler itself.
###Prompt the user for the file save###
output_name = tk.filedialog.asksaveasfilename(defaultextension='pdf')

UnicodeDecodeError Python 3.5.1 Email Script

I am attempting to send an email + attachment to an SMS gateway email. However I currently am getting a Unicode Decode: Error'Charmap' codec can't Decode Byte 0x8d in position 60
I'm not sure how to go about fixing this and would be interested in your advice. Bellow is my code and the Full Error.
import smtplib, os
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
msg = MIMEMultipart()
msg['Subject'] = 'Cuteness'
msg['From'] = 'sample#outlook.com'
msg['To'] = '111111111#messaging.sprintpcs.com'
msg.preamble = "Would you pet me? I'd Pet me so hard..."
here = os.getcwd()
file = open('cutecat.png')#the png shares directory with actual script
for here in file: #Error appears to be in this section
with open(file, 'rb') as fp:
img = MIMImage(fp.read())
msg.attach(img)
s = smtplib.SMTP('Localhost')
s.send_message(msg)
s.quit()
""" Traceback (most recent call last):
File "C:\Users\Thomas\Desktop\Test_Box\msgr.py", line 16, in <module>
for here in file:
File "C:\Users\Thomas\AppData\Local\Programs\Python\Python35-32\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 60: character maps to <undefined>"""
You're trying to open the file twice. First you have:
file = open('cutecat.png')
The default mode to open files is to read them in text mode. That is generally not what you want to do with a binary file like a PNG file.
And then you do:
for here in file:
with open(file, 'rb') as fp:
img = MIMImage(fp.read())
msg.attach(img)
You get an exception in the first line because Python is trying to decode the contents of a binary file as text and fails. The chances of this happening are quite high. It is unlikely that a binary file is also a valid text file in your standard encoding.
But even if that would have worked, for every line in the file you try to open the file again? This makes no sense!
Were you just copy/pasting from the examples, especially the third one? You should note that this example is incomplete. The variable pngfiles used in that example (and which should be a sequence of file names) is not defined.
Try this instead:
with open('cutecat.png', 'rb') as fp:
img = MIMImage(fp.read())
msg.attach(img)
Or if you want to include multiple files:
pngfiles = ('cutecat.png', 'kitten.png')
for filename in pngfiles:
with open(filename, 'rb') as fp:
img = MIMImage(fp.read())
msg.attach(img)

Resources