Creating a PDF with scripting in Blender - python

I am an all around newbie here (new to Blender, new to Python, and new to coding in general) so please bear with me.
I have a Blender script that generates a specific geometry and then renders an image. In the same script, I would then like to create a PDF file containing that image.
I have two different pdf generation scripts that work perfectly fine outside of Blender (I am using Spyder) but if I run the same code in Blender, I run into problems.
Here is the first one:
import datetime
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
import os.path
formatted_date = datetime.date.today()
date_str = str(formatted_date)
full_name = "Nachname, Vorname"
fpath = "I:/MedTech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/"
fname = full_name + "_" + date_str
fcount = 0
fcounts = fname + "_" + str(fcount) + ".pdf"
while os.path.isfile(fcounts)==True:
fcount += 1
fcounts = fname + "_" + str(fcount) + ".pdf"
print(fcounts)
fname = fcounts
doc = SimpleDocTemplate(fpath + fname,pagesize=letter,
rightMargin=72,leftMargin=72,
topMargin=72,bottomMargin=18)
Story=[]
KRIlogo = fpath + "Klinikum_rechts_der_Isar_logo.png"
lg_res_x = 1920
lg_res_y = 1080
lg_w = 50
lg_h = lg_w * lg_res_y/lg_res_x
lg = Image(KRIlogo, lg_w*mm, lg_h*mm)
lg.hAlign = 'RIGHT'
Story.append(lg)
wireIm = fpath + "20170102_red_20170207-092526.png"
bl_res_x = 1920
bl_res_y = 1080
im_w = 60
im_h = im_w * bl_res_y/bl_res_x
im = Image(wireIm, im_w*mm, im_h*mm)
im.hAlign = 'LEFT'
Story.append(im)
styles=getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
ntext = '<font size=12>%s</font>' % full_name
dtext = '<font size=12>%s</font>' % date_str
Story.append(Paragraph(ntext, styles["Normal"]))
Story.append(Spacer(1, 12))
Story.append(Paragraph(dtext, styles["Normal"]))
Story.append(Spacer(1, 12))
doc.build(Story)
Here is the second one:
import datetime
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.lib.utils import ImageReader
import os.path
formatted_date = datetime.date.today()
date_str = str(formatted_date)
full_name = "Nachname, Vorname"
fpath = "I:/MedTech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/"
fname = full_name + "_" + date_str
fcount = 0
fcounts = fname + "_" + str(fcount) + ".pdf"
while os.path.isfile(fcounts)==True:
fcount += 1
fcounts = fname + "_" + str(fcount) + ".pdf"
print(fcounts)
fname = fcounts
wireIm = fpath + "20170102_red_20170207-092526.png"
bl_res_x = 1920
bl_res_y = 1080
im_w = 60
im_h = im_w * bl_res_y/bl_res_x
WireImage = ImageReader(wireIm)
c = canvas.Canvas(fname)
c.drawImage(WireImage, 10, 10, width=60*mm)
c.showPage()
c.save()
Both scripts give me pretty much the same error:
Traceback (most recent call last):
File "I:\MedTech_Projekte\NAM\Studenten\WenokorRebecca_SA\BLENDER CODE\2016121
9 - Present\20170109 Face Align.blend\Text.002", line 58, in <module>
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\doctemplate.py", line 1200, in build
BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\doctemplate.py", line 956, in build
self.handle_flowable(flowables)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\doctemplate.py", line 821, in handle_flowable
if frame.add(f, canv, trySplit=self.allowSplitting):
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\frames.py", line 167, in _add
w, h = flowable.wrap(aW, h)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\flowables.py", line 484, in wrap
return self.drawWidth, self.drawHeight
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\flowables.py", line 478, in __getattr__
self._setup_inner()
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\flowables.py", line 442, in _setup_inner
img = self._img
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\platypus\flowables.py", line 472, in __getattr__
self._img = ImageReader(self._file)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 807, in __init__
annotateException('\nfileName=%r identity=%s'%(fileName,self.identity()))
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 1387, in annotateException
rl_reraise(t,v,b)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 144, in rl_reraise
raise v
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 801, in __init__
annotateException('\nImaging Library not available, unable to import bitmaps
only jpegs\nfileName=%r identity=%s'%(fileName,self.identity()))
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 1387, in annotateException
rl_reraise(t,v,b)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 144, in rl_reraise
raise v
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\lib\utils.py", line 799, in __init__
self._width,self._height,c=readJPEGInfo(self.fp)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\pdfbase\pdfutils.py", line 243, in readJPEGInfo
x = struct.unpack('B', image.read(1))
struct.error: unpack requires a bytes object of length 1
Imaging Library not available, unable to import bitmaps only jpegs
fileName='I:/MedTech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/Kli
nikum_rechts_der_Isar_logo.png' identity=[ImageReader#0xac09ef0 filename='I:/Med
Tech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/Klinikum_rechts_der
_Isar_logo.png']
fileName='I:/MedTech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/Kli
nikum_rechts_der_Isar_logo.png' identity=[ImageReader#0xac09ef0 filename='I:/Med
Tech_Projekte/NAM/Studenten/WenokorRebecca_SA/Spyder Scripts/Klinikum_rechts_der
_Isar_logo.png']
Error: Python script fail, look in the console for now...
When I use jpeg instead of png, I get the following:
Bibliotheken/Dokumente/Spyder Scripts/20170102_red_20170207-092526.jpeg
Traceback (most recent call last):
File "I:\MedTech_Projekte\NAM\Studenten\WenokorRebecca_SA\BLENDER CODE\2016121
9 - Present\20170109 Face Align.blend\Text.001", line 37, in <module>
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\pdfgen\canvas.py", line 1237, in save
self._doc.SaveToFile(self._filename, self)
File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\site-package
s\reportlab\pdfbase\pdfdoc.py", line 218, in SaveToFile
f = open(filename, "wb")
PermissionError: [Errno 13] Permission denied: 'Nachname, Vorname_2017-02-10_0.p
df'
Error: Python script fail, look in the console for now...
A lot of online forums mention the need for PIL and/or pillow when working with images. I don't fully understand how I would use those libraries in my code, but if the code works without them in Spyder, I don't see why it would all of a sudden need them in Blender.
Any help is very much appreciated!!! Feel free to ask for more information if my question is not clear :)
Thanks!

Python provides an environment that allows you to run python code, the standard install contains the ability to read files and print text to the console running the python script, among a variety of other things.
To use functionality that isn't included with the standard python install we can install and use third party modules, the reportlab module that you are using to create pdf's is an example of a third party module. The reportlab module knows how to create a pdf file, if you want it to add an image to the pdf then it will use another module that knows how to read image files. If a module used to read images is not available then it can't get the image information needed to add the image to the pdf but it can still create pdf's without images.
When you install python, the main program and the various modules are installed into specific places that can be found when needed. An installation of blender contains it's own copy of python and it's standard library, which isn't setup to use any normal installation of python that you may have. As you have found, you can manually add items to blender's version of python but the failure within blender of a script that works in spyder (which is using the standard installation of python) indicates you have missed something.
The second error is due to permissions that prevent a normal user writing to the applications folder, this happens as you are only specifying a filename which leads to trying to create the file in the current directory. You should be able to fix this error by using a full path to the target file instead of just the filename.
You may want to look at the subprocess module to run your pdf creation script externally from blender, passing the location of the image created with blender as an argument. This will let you run your python script to automate the tasks in blender, and do the pdf generation in the same setup that you are using within spyder.

In your terminal type
sudo gnome-terminal
This will give you root access and then try running the code

Related

moving files to new folder in FTP using Python

I am a bit lost. I'm trying to move a bunch of files to a new folder in FTP using python. I have tried a lot of function but what seems to work best is the ftp.rename function. In fact, it works to move only one file at a time to a new folder but it doesn't work to do it for a lot of files (like in my screenshot) using a for loop.
Do you know another technique to move efficiently files in a new folder?
Please help
This is the code to move a single file :
ftp = ftplib.FTP(host, username, password)
ftp.encoding = "utf-8"
FtpImage = ftp.mkd("image")
ftp.rename("img1.png", "/image/img1.png")
ftp.quit()
This is the code to move a bunch of files at the same time :
ftp = ftplib.FTP(host, username, password)
ftp.encoding = "utf-8"
#creating a list with all my files
dirList = ftp.nlst()
#creating a folder
ftpFolder = ftp.mkd("folder1")
#moving my file using their name and adding the folder1 to their name
for file in dirList:
ftp.rename(file, "/folder1/" + file)
# shutil.move(file, "/folder1/" + file )
ftp.quit()
Error that I get when I run the second programm:
DeprecationWarning: The Tix Tk extension is unmaintained, and the tkinter.tix wrapper module is deprecated in favor of tkinter.ttk
from tkinter.tix import IMAGETEXT
Traceback (most recent call last):
File "\\wsl$\Ubuntu\home\q******\projet_python\FTP-sorting\test.py", line 26, in <module>
ftp.rename(file, "/folder1/")
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\ftplib.py", line 604, in rename
return self.voidcmd('RNTO ' + toname)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\ftplib.py", line 286, in voidcmd
return self.voidresp()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\ftplib.py", line 259, in voidresp
resp = self.getresp()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\ftplib.py", line 254, in getresp
raise error_perm(resp)
ftplib.error_perm: 550 Rename /folder1/: Device or resource busy
I was able to find a way to sort my different files :
I had first to sort my dirList (list with all the files) with new sub list (like allDivers) and then I used the following code
for file in allDivers:
destination_folder = "/divers/"
destination = destination_folder + file
ftp.rename(file, destination )

No such file or directory: 'GoogleNews-vectors-negative300.bin'

I have this code :
import gensim
filename = 'GoogleNews-vectors-negative300.bin'
model = gensim.models.KeyedVectors.load_word2vec_format(filename, binary=True)
and this is my folder organization thing :
image of my folder tree that shows that the .bin file is in the same directory as the file calling it, the file being ai_functions
But sadly I'm not sure why I'm having an error saying that it can't find it. Btw I checked, I am sure the file is not corrupted. Any thoughts?
Full traceback :
File "/Users/Ile-Maurice/Desktop/Flask/flaskapp/run.py", line 1, in <module>
from serv import app
File "/Users/Ile-Maurice/Desktop/Flask/flaskapp/serv/__init__.py", line 13, in <module>
from serv import routes
File "/Users/Ile-Maurice/Desktop/Flask/flaskapp/serv/routes.py", line 7, in <module>
from serv.ai_functions import checkplagiarism
File "/Users/Ile-Maurice/Desktop/Flask/flaskapp/serv/ai_functions.py", line 31, in <module>
model = gensim.models.KeyedVectors.load_word2vec_format(filename, binary=True)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/gensim/models/keyedvectors.py", line 1629, in load_word2vec_format
return _load_word2vec_format(
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/gensim/models/keyedvectors.py", line 1955, in _load_word2vec_format
with utils.open(fname, 'rb') as fin:
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/smart_open/smart_open_lib.py", line 188, in open
fobj = _shortcut_open(
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/smart_open/smart_open_lib.py", line 361, in _shortcut_open
return _builtin_open(local_path, mode, buffering=buffering, **open_kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'GoogleNews-vectors-negative300.bin'
The 'current working directory' that the Python process will consider active, and thus will use as the expected location for your plain relative filename GoogleNews-vectors-negative300.bin, will depend on how you launched Flask.
You could print out the directory to be sure – see some ways at How do you properly determine the current script directory? – but I suspect it may just be the /Users/Ile-Maurice/Desktop/Flask/flaskapp/ directory.
If so, you could relatively-reference your file with the path relative to the above directory...
serv/GoogleNews-vectors-negative300.bin
...or you could use a full 'absolute' path...
/Users/Ile-Maurice/Desktop/Flask/flaskapp/serv/GoogleNews-vectors-negative300.bin
...or you could move the file up to its parent directory, so that it is alonside your Flask run.py.

Reportlab and PIL : unpack requires a string argument of length 1 Imaging Library not available, unable to import bitmaps only jpegs

I've an issue using ReportLab abd PIL (in Flask project), using Vagrant's VM (2.2.3)
The error is located using the readJPEGInfo() function. The PNG file (-rwxrwxr-- 1 www-data www-data 21K juin 22 2018) is there :
site_media/img/84/5_1_pied_de_page.png: PNG image data, 1066 x 47, 8-bit/color RGBA, non-interlaced
The error message :
(unpack requires a string argument of length 1 Imaging Library not available, unable to import bitmaps only jpegs
fileName='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png' identity=[ImageReader#0x7fdd75f2a110
filename='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png']
fileName='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png' identity=[ImageReader#0x7fdd75f2a110
filename='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png'] --> <class 'struct.error'> => Traceback (most recent call last): File "/var/www/my_project/my_project/flask_my_project/views.py", line 206, in zonesmeteo createDisplay(t, config, tabAlerts, demain, message)
File "/var/www/my_project/my_project/flask_my_project/utils.py", line 29, in createDisplay tr.generateFiles()
File "/var/www/my_project/my_project/cron_dept_treatments/84.py", line 64, in generateFiles self.dicoFolders)
File "/var/www/my_project/my_project/cron_dept_treatments/84.py", line 258, in __init__ table5.drawOn(self.c,15,12)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 111, in drawOn self._drawOn(canvas)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 92, in _drawOn self.draw()#this is the bit you overload
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/tables.py", line 1425, in draw self._drawCell(cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight))
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/tables.py", line 1558, in _drawCell v.drawOn(self.canv,x,y)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 111, in drawOn self._drawOn(canvas)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 92, in _drawOn self.draw()#this is the bit you overload
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 511, in draw self.canv.drawImage( self._img or self.filename,
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/platypus/flowables.py", line 481, in __getattr__ self._img = ImageReader(self._file)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 810, in __init__ annotateException('\nfileName=%r identity=%s'%(fileName,self.identity()))
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 1390, in annotateException rl_reraise(t,v,b)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 804, in __init__ annotateException('\nImaging Library not available, unable to import bitmaps only jpegs\nfileName=%r identity=%s'%(fileName,self.identity()))
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 1390, in annotateException rl_reraise(t,v,b)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 802, in __init__ self._width,self._height,c=readJPEGInfo(self.fp)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/pdfbase/pdfutils.py", line 243, in readJPEGInfo x = struct.unpack('B', image.read(1)) error: unpack requires a string argument of length 1 Imaging Library not available, unable to import bitmaps only jpegs fileName='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png' identity=[ImageReader#0x7fdd75f2a110
filename='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png'] fileName='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png' identity=[ImageReader#0x7fdd75f2a110
filename='/var/www/my_project/my_project/site_media/img/20/5_1_pied_de_page.png'] )
The part of pip freeze (python 2.7 ):
Pillow==2.6.1
reportlab==3.4.0
The user/group :
$ cat /etc/group | grep data
www-data:x:33:vagrant,apache,nginx,httpd,www-data,www-user
So, I've do a simple python test file :
import reportlab, PIL
from reportlab.platypus import SimpleDocTemplate
from reportlab.pdfgen import canvas
from reportlab.platypus import Frame, Image
png_file = "/var/www/test/5_1_pied_de_page.png"
img=canvas.Canvas(png_file)
my_doc = SimpleDocTemplate('myfile.pdf')
parts=[]
parts.append(Image(png_file))
my_doc.build(parts)
Same errors :
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/lib/utils.py", line 802, in __init__
self._width,self._height,c=readJPEGInfo(self.fp)
File "/home/vagrant/.virtualenvs/my_project/lib/python2.7/site-packages/reportlab/pdfbase/pdfutils.py", line 243, in readJPEGInfo
x = struct.unpack('B', image.read(1))
struct.error: unpack requires a string argument of length 1
Imaging Library not available, unable to import bitmaps only jpegs
fileName='/var/www/my_project/my_project/site_media/img/84/5_1_pied_de_page.png' identity=[ImageReader#0x7fc9223f3e50 filename='/var/www/my_project/my_project/site_media/img/84/5_1_pied_de_page.png']
fileName='/var/www/my_project/my_project/site_media/img/84/5_1_pied_de_page.png' identity=[ImageReader#0x7fc9223f3e50 filename='/var/www/my_project/my_project/site_media/img/84/5_1_pied_de_page.png']
(my_project)
And, in my test file, I've convert the PNG in JPG : No error, but the pdf file is blank :)
Thanks.
F.
$ uname -a
Linux vm 4.4.0-131-generic #157-Ubuntu SMP Thu Jul 12 15:51:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
I believe you need to get it into a Reportlab flowable object. Even if I would not use PIL directly in this case, I can share how I get it to work (here with a frame, but works also without). It works on most pic formats, incl png, pls note I have not tested the code below.
from reportlab.lib.units import cm
from reportlab.platypus import Image, Frame, PageTemplate, BaseDocTemplate
png_file = "/var/www/test/5_1_pied_de_page.png"
picture_frame = Frame(
x1 =10 * cm, # From left
y1 =26 * cm, # From bottom
height =9 * cm,
width =9 * cm)
frontpage = PageTemplate(id='FrontPage', onPage='', frames=[picture_frame])
picture = Image(png_file, 9 * cm, 6 * cm, hAlign='RIGHT')
my_doc = BaseDocTemplate('myfile.pdf', pagesize=A4)
my_doc.addPageTemplates(frontpage)
parts = []
parts.append(picture)
my_doc.build(parts)

Tablib xlsx file badZip file issue

I am getting error on opening xlsx extension file in windows 8 using tablib library.
python version - 2.7.14
error is as follows:
python suit_simple_sheet_product.py
Traceback (most recent call last):
File "suit_simple_sheet_product.py", line 19, in <module>
data = tablib.Dataset().load(open(BASE_PATH).read())
File "C:\Python27\lib\site-packages\tablib\core.py", line 446, in load
format = detect_format(in_stream)
File "C:\Python27\lib\site-packages\tablib\core.py", line 1157, in detect_format
if fmt.detect(stream):
File "C:\Python27\lib\site-packages\tablib\formats\_xls.py", line 25, in detect
xlrd.open_workbook(file_contents=stream)
File "C:\Python27\lib\site-packages\xlrd\__init__.py", line 120, in open_workbook
zf = zipfile.ZipFile(timemachine.BYTES_IO(file_contents))
File "C:\Python27\lib\zipfile.py", line 770, in __init__
self._RealGetContents()
File "C:\Python27\lib\zipfile.py", line 811, in _RealGetContents
raise BadZipfile, "File is not a zip file"
zipfile.BadZipfile: File is not a zip file
path location is as follows =
BASE_PATH = 'C:\Users\anju\Downloads\automate\catalog-5090 fabric detail and price list.xlsx'
Excel .xlsx files are actually zip files. In order for the unzip to work correctly, the file must be opened in binary mode, as such your need to open the file using:
import tablib
BASE_PATH = r'c:\my folder\my_test.xlsx'
data = tablib.Dataset().load(open(BASE_PATH, 'rb').read())
print data
Add r before your string to stop Python from trying to interpret the backslash characters in your path.

Django: How to allow a Suspicious File Operation / copy a file

I want to do a SuspiciousFileOperation which django disallows by default.
I am writing a command (to run via manage.py importfiles) to import a given directory structure on the real file system in my self written filestorage in Django.
I think, this is my relevant code:
def _handle_directory(self, directory_path, directory):
for root, subFolders, files in os.walk(directory_path):
for filename in files:
self.cnt_files += 1
new_file = File(directory=directory, filename=filename, file=os.path.join(root, filename),
uploader=self.uploader)
new_file.save()
The backtrace is:
Traceback (most recent call last):
File ".\manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 399, in execute_from_command_line
utility.execute()
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 242, in run_from_argv
self.execute(*args, **options.__dict__)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 285, in execute
output = self.handle(*args, **options)
File "D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py", line 53, in handle
self._handle_directory(args[0], root)
File "D:\Development\github\Palco\engine\filestorage\management\commands\importfiles.py", line 63, in _handle_directory
new_file.save()
File "D:\Development\github\Palco\engine\filestorage\models.py", line 157, in save
self.sha512 = hashlib.sha512(self.file.read()).hexdigest()
File "C:\Python27\lib\site-packages\django\core\files\utils.py", line 16, in <lambda>
read = property(lambda self: self.file.read)
File "C:\Python27\lib\site-packages\django\db\models\fields\files.py", line 46, in _get_file
self._file = self.storage.open(self.name, 'rb')
File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 33, in open
return self._open(name, mode)
File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 160, in _open
return File(open(self.path(name), mode))
File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 261, in path
raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
django.core.exceptions.SuspiciousFileOperation: Attempted access to 'D:\Temp\importme\readme.html' denied.
The full model can be found at GitHub. The full command is currently on gist.github.com available.
If you do not want to check the model: the attribute file of my File class is a FileField.
I assume, this problem happens, because I am just "linking" to the file found. But I need to copy it, huh? How can I copy the file into the file?
In Django, SuspiciousFileOperation can be avoid by read the file from external dir and make a tmp file within the project media then save in the appropriate file filed as below
import tempfile
file_name="file_name.pdf"
EXT_FILE_PATH = "/home/somepath/"
file_path = EXT_FILE_PATH + file_name
if exists(file_path):
#create a named temporary file within the project base , here in media
lf = tempfile.NamedTemporaryFile(dir='media')
f = open(file_path, 'rb')
lf.write(f.read())
#doc object with file FileField.
doc.file.save(file_name, File(lf), save=True)
lf.close()
I haven't faced similar problem but related issue. I have recently upgraded Django 1.8 to 1.11.
Now I am getting the following error if try to save a file in a model having FileField field:
SuspiciousFileOperation at /api/send_report/
The joined path (/vagrant/tmp/test_file.pdf) is located outside of the base path component (/vagrant/media)
My model where I want to save the file:
class Report(BaseModel):
file = models.FileField(max_length=200, upload_to=os.path.join(settings.REPORTS_URL, '%Y/week_%W/'))
type = models.CharField(max_length=20, verbose_name='Type', blank=False, default='', db_index=True)
I am trying following codes to save the file from tmp folder which is not located in MEDIA_ROOT:
from django.core.files import File
filepath = "/vagrant/tmp/test_file.pdf"
file = File(open(filepath, "rb"))
report_type = "My_report_type"
report = Report.objects.create(
file=file,
type=report_type,
)
What I have done to solve the issue:
import os
from django.core.files import File
filepath = "/vagrant/tmp/test_file.pdf"
file = File(open(filepath, "rb"))
file_name = os.path.basename(file.name)
report_type = "My_report_type"
report = Report.objects.create(
type=report_type,
)
report.file.save(file_name, file, save=True)
Hope it will help someone.
Analyzing this part of stacktrace:
File "C:\Python27\lib\site-packages\django\core\files\storage.py", line 261, in path
raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
leads to the standard Django FileSystemStorage. It expects files to be within your MEDIA_ROOT. Your files can be anywhere in the file system, therefore this problem occurs.
You should pass file-like object instead of a path to your File model. The easiest way to achieve that would be to use Django File class, which is a wrapper around python file-like objects. See File object documentation for more details.
Update:
Ok, I am suggesting here a route taken from the docs:
from django.core.files import File as FileWrapper
def _handle_directory(self, directory_path, directory):
for root, subFolders, files in os.walk(directory_path):
for filename in files:
self.cnt_files += 1
new_file = File(
directory=directory, filename=filename,
file=os.path.join(root, filename),
uploader=self.uploader)
with open(os.path.join(root, filename), 'r') as f:
file_wrapper = FileWrapper(f)
new_file = File(
directory=directory, filename=filename,
file=file_wrapper,
uploader=self.uploader)
new_file.save()
If it works it should copy the file to the location provided by your secure_storage callable.
Check if there is slash before your filepath
file_item = models.FileField(upload_to=content_file_name)
def content_file_name(username, filename):
return '/'.join(['content', username, filename])
Note here "content" not "/content". That was the problem for me.

Categories

Resources